Code Monkey home page Code Monkey logo

wait-on-check-action's Introduction

Wait On Check Action

![RSpec Tests][rspec_shield]

Pause a workflow until a job in another workflow completes successfully.

This action uses the [Checks API][checks_api] to poll for check results. On success, the action exit allowing the workflow resume. Otherwise, the action will exit with status code 1 and fail the whole workflow.

This is a workaround to GitHub's limitation of non-interdependent workflows ๐ŸŽ‰

You can run your workflows in parallel and pause a job until a job in another workflow completes successfully.

Minimal example

name: Test

on: [push]

jobs:
  test:
    name: Run tests
    runs-on: ubuntu-latest
      steps:
        ...
name: Publish

on: [push]

jobs:
  publish:
    name: Publish the package
    runs-on: ubuntu-latest
    steps:
      - name: Wait for tests to succeed
        uses: lewagon/[email protected]
        with:
          ref: ${{ github.ref }}
          check-name: 'Run tests'
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          wait-interval: 10
      ...

GHE Support

For GHE support you just need to pass in api-endpoint as an input.

name: Publish

on: [push]

jobs:
  publish:
    name: Publish the package
    runs-on: ubuntu-latest
    steps:
      - name: Wait for tests to succeed
        uses: lewagon/[email protected]
        with:
          ref: ${{ github.ref }}
          check-name: 'Run tests'
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          api-endpoint: YOUR_GHE_API_BASE_URL # Fed to https://octokit.github.io/octokit.rb/Octokit/Configurable.html#api_endpoint-instance_method
      ...

Alternatives

If you can keep the dependent jobs in a single workflow:

name: Test and publish

on: [push]

jobs:
  test:
    runs-on: ubuntu-latest
    steps: ...

  publish:
    runs-on: ubuntu-latest
    needs: test
    steps: ...

If you can run dependent jobs in a separate workflows in series:

name: Publish

on:
  workflow_run:
    workflows: ['Test']
    types:
      - completed

A real-world scenario

  • Pushes to master trigger a test job to be run against the application code.

  • Pushes to master also trigger a webhook that builds an image on external service such as Quay.

  • Once an image is built, a repository_dispatch hook is triggered from a third-party service. This triggers a deploy job.

  • We don't want the deploy job to start until the master branch passes its test job.

name: Trigger deployment on external event

on:
  # https://github.com/lewagon/quay-github-actions-dispatch
  repository_dispatch:
    types: [build_success]

jobs:
  deploy:
    if: startsWith(github.sha, github.event.client_payload.text)
    name: Deploy a new image
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2

      - name: Wait for tests to succeed
        uses: lewagon/[email protected]
        with:
          ref: master
          check-name: test
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          wait-interval: 20

      - name: Save the DigitalOcean kubeconfig
        uses: digitalocean/action-doctl@master
        env:
          DIGITALOCEAN_ACCESS_TOKEN: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
        with:
          args: kubernetes cluster kubeconfig show my-cluster > $GITHUB_WORKSPACE/.kubeconfig

      - name: Upgrade/install chart
        run: export KUBECONFIG=$GITHUB_WORKSPACE/.kubeconfig && make deploy latest_sha=$(echo $GITHUB_SHA | head -c7)}}

Parameters

Check name

Check name goes according to the jobs.<job_id>.name parameter.

In this case the job's name is 'test':

jobs:
  test:
    runs-on: ubuntu-latest
      steps:
      ...

In this case the name is 'Run tests':

jobs:
  test:
    name: Run tests
    runs-on: ubuntu-latest
      steps:
      ...

In this case the names will be:

  • Run tests (3.6)

  • Run tests (3.7)

jobs:
  test:
    name: Run tests
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python: [3.6, 3.7]

To inspect the names as they appear to the API:

curl -u username:$token \
https://api.github.com/repos/OWNER/REPO/commits/REF/check-runs \
-H 'Accept: application/vnd.github.antiope-preview+json' | jq '[.check_runs[].name]'

Running workflow name

If you would like to wait for all other checks to complete you may set running-workflow-name to the name of the current job and not set a check-name parameter.

name: Publish

on: [push]

jobs:
  publish:
    name: Publish the package
    runs-on: ubuntu-latest
    steps:
      - name: Wait for other checks to succeed
        uses: lewagon/[email protected]
        with:
          ref: ${{ github.ref }}
          running-workflow-name: 'Publish the package'
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          wait-interval: 10
      ...

Using running workflow name in reusable workflows

Using this action in a reusable workflow means accepting a constraint that all calling jobs will have the same name. For example, all calling workflows must call their jobs caller (or some more relevant constant) so that if the reused workflow containing the job that uses this action to wait is called callee then the task can successfully wait on caller / callee. Working example follows.

.github/workflows/caller.yml

on:
  push:
jobs:
  caller:
    uses: ./.github/workflows/callee.yml

.github/workflows/callee.yml

on:
  workflow_call:
jobs:
  callee:
    runs-on: ubuntu-latest
    steps:
      - name: Wait for Other Workflows
        uses: lewagon/[email protected]
        with:
          ref: ${{ github.ref }}
          running-workflow-name: 'caller / callee'
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          wait-interval: 10

Allowed conclusions

By default, checks that conclude with either success or skipped are allowed, and anything else is not. You may configure this with the allowed-conclusions option, which is a comma-separated list of conclusions.

name: Publish

on: [push]

jobs:
  publish:
    name: Publish the package
    runs-on: ubuntu-latest
    steps:
      - name: Wait for tests to succeed
        uses: lewagon/[email protected]
        with:
          ref: ${{ github.ref }}
          check-name: 'Run tests'
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          wait-interval: 10
          allowed-conclusions: success,skipped,cancelled
      ...

Using check-regexp

Similar to the check-name parameter, this filters the checks to be waited but using a Regular Expression (aka regexp) to match the check name (jobs.<job_id>.name)

Example of use:

name: Wait using check-regexp
on:
  push:

jobs:
  wait-for-check-regexp:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2

      - name: Wait on tests
        uses: ./
        with:
          ref: ${{ github.sha }}
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          running-workflow-name: wait-for-check-regexp
          check-regexp: .?-task

Wait interval (optional, default: 10)

As it could be seen in many examples, there's a parameter wait-interval, and sets a time in seconds to be waited between requests to the GitHub API. The default time is 10 seconds.

Verbose (optional, default: true)

If true, it prints some logs to help understanding the process (checks found, filtered, conclussions, etc.)

Auto-pagination

Since we are using Octokit for using GitHub API, we are subject to their limitations. One of them is the pagination max size: if we have more than 100 workflows running, the auto-pagination won't help. More about Octokit auto-pagination can be found here The solution would be to fetch all pages to gather all running workflows if they're more than 100, but it's still no implemented.

Tests

There are sample workflows in the .github/workflows directory. Two of them are logging tasks to emulate real-world actions being executed that have to be waited. The important workflows are the ones that use the wait-on-check-action.

A workflow named "wait_omitting-check-name" waits for the two simple-tasks, while the one named "wait_using_check-name" only waits for "simple-task".

wait-on-check-action's People

Contributors

matiasalbarello avatar ssaunier avatar billy- avatar sshane avatar codezninja avatar dependabot[bot] avatar axtgr avatar ditman avatar eafzali avatar erikerikson avatar guidoiaquinti avatar hsbt avatar joellefkowitz avatar pietrovismara avatar srodriguezo avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.