A human and robot hand drawing each other

Advanced workflow configurations in GitHub Actions

Bekah Whittle
Bekah Whittle // Director, Field Services // GitHub

In this guide, we’ll discuss advanced techniques for optimizing GitHub Actions workflows, including managing workflow concurrency, implementing conditional statements, and augmenting workflows with in-house scripts—all aimed at streamlining and accelerating your development pipeline. In this guide we'll be joined by Cariad (the automotive software company and subsidiary of Volkswagen group) to hear how they have found success with Actions.


In this guide, you will learn:

  • How to manage workflow concurrency

  • How to leverage conditional statements for improved extensibility

  • How to accelerate innersource strategies by augmenting workflows with scripts


Managing workflow prioritization and cancellation

As your development environment expands, the need to manage multiple workflows efficiently becomes crucial. Actions offers a feature for controlling this: concurrency. This setting enables you to prioritize specific workflow runs over others, giving you control over resource allocation and ultimately speeding up your development process.

Prioritization

In Actions, you can prioritize one workflow over another by defining a specific concurrency group. By doing so, you can outline which designated workflow will automatically be moved to the top of the execution queue, thereby receiving priority treatment.

Here's how to setup a concurrency group:

concurrency: 
  group: 'my-concurrency-group'

In our setup, we don't necessarily prioritize one workflow over another. Instead, our focus is on preventing simultaneous or parallel runs of workflows, which could lead to conflicts and inconsistencies in our operations. We use concurrency groups to protect against this. These groups act as a mechanism to regulate the execution of our workflows, ensuring that they do not run in parallel. This strategy not only helps us avoid conflicts but also maintains the consistency and integrity of our deployments. This is particularly crucial for us, as failing to regulate concurrent runs could lead to complex and undesirable scenarios.

Andre Hacke
Andre Hacke // Senior Product Owner // CARIAD

Cancel in-progress runs

When using concurrency, setting cancel-in-progress to true cancels any other runs in progress within the same concurrency group, ensuring that only the most recent workflow run is executed.

concurrency: 
  group: 'my-concurrency-group'
  cancel-in-progress: true

This is particularly useful when you have multiple runs queued. It ensures that your latest commit is the one being tested and prevents older, redundant runs from consuming precious resources.

Adding precision to workflow execution

Actions also allows for conditional logic, which can be used to manage workflow execution as your organization grows more complex. For example, you can achieve greater control and adaptability by setting the precise conditions under which a job or step is executed.

How conditional statements work

In Actions, conditional statements are defined using the if keyword. These conditions determine whether a job should be executed or skipped.

Here's a sample snippet:

jobs:
  build:
    if: github.repository == 'docs-internal' || github.repository == 'GitHub-docs'

In this example, the job will only be executed if the GitHub repository is either docs-internal or GitHub-docs.

Pairing conditional statements with secrets

Conditional statements can also be paired with secrets for even more refined control. For instance, you could set a condition that only runs a job if a secret value matches a particular string.

jobs:
  deploy:
    if: secrets.ENVIRONMENT == 'production'

In this case, the job only runs when the ENVIRONMENT secret is set to production, which adds an additional layer of security and control to your workflows.

With conditional statements, you not only get more control over your workflows but you’re also able to tailor your actions to fit specific project or security needs. This is especially valuable for managing resources effectively and maintaining the integrity of your development processes.

Augmenting workflows with scripts

Scripts are a straightforward way to manage complexity in Actions. By incorporating scripts into your workflows, you can offload certain operations from the main workflow file, thereby enhancing reusability and maintenance by increasing modularity and making your workflow files easier to read. 

Scripts aren’t just about compartmentalizing code; they’re about creating reusable, maintainable components that can be easily incorporated into various workflows, leading to a more efficient innersourcing model.

How to incorporate scripts into workflows

To call a script within an Actions workflow, you specify the path to the script in the run section of your YAML file. Here’s a snippet to illustrate:

jobs:
  build:
    steps:
      - name: Execute custom script
        run: ./path/to/your/script.sh

As your organization continues to grow, these advanced tactics—concurrency, conditional statements, and scripts—will prove indispensable.

Up next: Building your first custom GitHub Action

In our next guide, we will focus on custom actions and walk you through how to build one using action.yml for configuration and JavaScript for the logic. This will set you up to automate your workflows effectively on GitHub.