{"id":14985990,"url":"https://github.com/re-actors/alls-green","last_synced_at":"2025-04-09T13:05:28.826Z","repository":{"id":44760024,"uuid":"434447646","full_name":"re-actors/alls-green","owner":"re-actors","description":"A check for whether the dependency jobs are all green.","archived":false,"fork":false,"pushed_at":"2023-12-26T16:51:25.000Z","size":70,"stargazers_count":113,"open_issues_count":9,"forks_count":12,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-10-22T03:24:12.884Z","etag":null,"topics":["action","actions","github-actions","hacktoberfest"],"latest_commit_sha":null,"homepage":"https://github.com/marketplace/actions/alls-green","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/re-actors.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":["https://www.comebackalive.in.ua/donate","https://github.com/vshymanskyy/StandWithUkraine#for-maintainers-and-authors","https://www.paypal.me/webknjazCZ","https://webknjaz.me"],"github":["webknjaz"],"ko_fi":"webknjaz","liberapay":"webknjaz"}},"created_at":"2021-12-03T02:58:30.000Z","updated_at":"2024-10-15T06:27:19.000Z","dependencies_parsed_at":"2024-06-18T15:13:45.144Z","dependency_job_id":"654ab14b-f429-4a80-b233-c2bf4f1e4e18","html_url":"https://github.com/re-actors/alls-green","commit_stats":{"total_commits":52,"total_committers":3,"mean_commits":"17.333333333333332","dds":0.05769230769230771,"last_synced_commit":"223e4bb7a751b91f43eda76992bcfbf23b8b0302"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/re-actors%2Falls-green","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/re-actors%2Falls-green/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/re-actors%2Falls-green/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/re-actors%2Falls-green/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/re-actors","download_url":"https://codeload.github.com/re-actors/alls-green/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248045230,"owners_count":21038553,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["action","actions","github-actions","hacktoberfest"],"created_at":"2024-09-24T14:12:05.986Z","updated_at":"2025-04-09T13:05:28.802Z","avatar_url":"https://github.com/re-actors.png","language":"Python","funding_links":["https://www.comebackalive.in.ua/donate","https://github.com/vshymanskyy/StandWithUkraine#for-maintainers-and-authors","https://www.paypal.me/webknjazCZ","https://webknjaz.me","https://github.com/sponsors/webknjaz","https://ko-fi.com/webknjaz","https://liberapay.com/webknjaz","https://github.com/sponsors/graingert","https://github.com/sponsors/reaperhulk"],"categories":["Python"],"sub_categories":[],"readme":"# alls-green\n\nA check for whether the dependency jobs are all green.\n\n## Why?\n\nDo you have more than one job in your GitHub Actions CI/CD workflows\nsetup? Do you use branch protection? Are you annoyed that you have to\nmanually update the required checks in the repository settings hoping\nthat you don't forget something on each improvement of the test matrix\nstructure?\n\nYeah.. me too! But there's a solution — you can make a single `check`\njob listing all of the other jobs in its `needs` list. How about that?\n🤯 Now you can add only that single job to your branch protection\nsettings and you won't have to maintain that list manually anymore.\n\nRight..? Wrong 🙁 — apparently, in case when something fails, the\n`check` job's result is set to `skipped` and not `failed` as one would\nexpect. This is problematic and requires extra work to get it right.\nSome of it is iteration over the needed jobs and checking that all their\nresults are set to success but it's no fun to maintain this sort of\nthing in many different repositories. Also, it is mandatory to make the\n`check` job run always, not only when all of the needed jobs succeed.\n\nThis is why I decided to make this action to simplify the maintenance.\n\n--[@webknjaz]\n\n:wq\n\n\n## Usage\n\nTo use the action add a `check` job to your workflow file (e.g.\n`.github/workflows/ci-cd.yml`) following the example below:\n\n\n```yml\n---\non:\n  pull_request:\n  push:\n\njobs:\n  build:\n    ...\n\n  docs:\n    ...\n\n  linters:\n    ...\n\n  package-linters:\n    needs:\n    - build\n    ...\n\n  tests:\n    needs:\n    - build\n    ...\n\n  check:\n    if: always()\n\n    needs:\n    - docs\n    - linters\n    - package-linters\n    - tests\n\n    runs-on: Ubuntu-latest\n\n    steps:\n    - name: Decide whether the needed jobs succeeded or failed\n      uses: re-actors/alls-green@release/v1\n      with:\n        allowed-failures: docs, linters\n        allowed-skips: non-voting-flaky-job\n        jobs: ${{ toJSON(needs) }}\n...\n```\n\n\n## Options\n\nThere are three options — `allowed-failures`, `allowed-skips` and\n`jobs`. The first two are optional but `jobs` is mandatory.\n`allowed-failures` tells the action which jobs should not affect the\noutcome if they don't succeed, by default all the jobs will\nbe \"voting\". Same goes for `allowed-skips` — it won't allow the listed\njobs to affect the outcome if they are skipped but are still \"voting\" in\ncase they run. `jobs` is an object representing the jobs that should\naffect the decision of whether the pipeline failed or not, it is\nimportant to pass a JSON-serialized `needs` context to this argument.\n\n*Important:* For this to work properly, it is a must to have the job\nalways run, otherwise GitHub will make it `skipped` when any of the\ndependencies fail. In some contexts, `skipped` is interpreted as\n`success` which may lead to undersired, unobvious and even dangerous (as\nin security breach \"dangerous\") side-effects.\n\n\n## Outputs\n\n\n### ``failure``\n\nWhether this check decided that the job matrix failed.\n\n\n### ``result``\n\nFailure or success result of the job matrix.\n\n\n### ``success``\n\nWhether this check decided that the job matrix succeeded.\n\n\n## Gotchas\n\nAn attentive reader may have noticed that there is no clear way to\nallow failures for specific job generated by matrixes in a simple\nmanner, through action inputs. This is due to the fact that those\nindividual matrix job statuses are not exposed by the GitHub platform.\n\nAlthough, there is a solution — use a `continue-on-error`\njob-level setting with a dynamic matrix-dependent value. In this case,\nthe matching jobs will not influence the resulting outcome of the\nwhole matrix and this action will \"see\" that as a success (provided\nthat the jobs that are not allowed to fail succeed, of course).\n\nHere's a simplified example of what testing against an unstable\nPython 3.11 release that is allowed to fail might look like:\n```yaml\n---\n\n...  # Some sections have been removed from the example to simplify it\n\njobs:\n  tests:\n    runs-on: ubuntu-latest\n\n    matrix:\n       python-version:\n       - \u003e-\n         3.10\n       - ~3.11.0-0\n\n    continue-on-error: \u003e-\n      ${{ contains(matrix.python-version, '~') \u0026\u0026 true || false }}\n\n    steps:\n    - ...\n\n  check:\n    if: always()\n\n    needs:\n    - tests\n\n    runs-on: ubuntu-latest\n\n    steps:\n    - name: Decide whether the needed jobs succeeded or failed\n      uses: re-actors/alls-green@release/v1\n      with:\n        jobs: ${{ toJSON(needs) }}\n\n...\n```\n\n\n## Does anybody actually use this?\n\nWe've seen it being integrated into some projects of [@aio-libs]\n(notably, [aiohttp]), [Ansible] [Collections][Ansible Collections]\n[Community][Ansible Community], [attrs], [@CherryPy], [conda],\n[coveragepy], [Open edX], [pip-tools], [setuptools], [structlog],\n[spaceship-prompt], [Towncrier], [@PyCA], [@PyPA] and [@pytest]\necosystems. And here's more:\nhttps://github.com/re-actors/alls-green/network/dependents.\n\n\n## Whose idea is this?\n\nMy inspiration came from [Zuul] — a project [gating] system that\npractices having one \"check-gate\" that depends on multiple individual\nchecks. Later when I started implementing this practice across the\nprojects that I maintain, I discovered that I was not the only one who\ngot the same idea [@graingert] posted a similar solution on the [GitHub\nCommunity Forum][forum:check]. At some point I noticed that GitHub's\nauto-merge merges Dependabot PRs that are broken despite having branch\nprotection enabled in the [aiohttp] repository, it wasn't obvious why.\nI stumbled on the solution accidentally, it was implemented in the\n[PyCA/cryptography] repository — the credit for that goes to\n[@reaperhulk]. He listed all of the needed jobs manually in the `check`.\nWith those findings I've spent some time on experimentation and\ncomposing a more generic solution — this is how this GitHub Action came\nto be.\n\n\n## License\n\nThe contents of this project is released under the\n[BSD 3-clause license].\n\n\n[aiohttp]: https://github.com/aio-libs/aiohttp\n[Ansible]: https://github.com/ansible\n[Ansible Collections]: https://github.com/ansible-collections\n[Ansible Community]: https://github.com/ansible-community\n[attrs]: https://github.com/python-attrs/attrs\n[BSD 3-clause license]: LICENSE.md\n[conda]: https://github.com/conda/conda\n[coveragepy]: https://github.com/nedbat/coveragepy\n[forum:check]:\nhttps://github.com/orgs/community/discussions/26733#discussioncomment-3253151\n[gating]: https://gating.dev\n[Open edX]: https://github.com/openedx/edx-platform\n[pip-tools]: https://github.com/jazzband/pip-tools\n[PyCA/cryptography]: https://github.com/PyCA/cryptography\n[setuptools]: https://github.com/PyPA/setuptools\n[spaceship-prompt]: https://github.com/spaceship-prompt/spaceship-prompt\n[structlog]: https://github.com/hynek/structlog\n[Towncrier]: https://github.com/twisted/towncrier\n[Zuul]: https://zuul-ci.org\n[@aio-libs]: https://github.com/aio-libs\n[@CherryPy]: https://github.com/cherrypy\n[@graingert]: https://github.com/sponsors/graingert\n[@PyCA]: https://github.com/PyCA\n[@PyPA]: https://github.com/PyPA\n[@pytest]: https://github.com/pytest-dev\n[@reaperhulk]: https://github.com/sponsors/reaperhulk\n[@webknjaz]: https://github.com/sponsors/webknjaz\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fre-actors%2Falls-green","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fre-actors%2Falls-green","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fre-actors%2Falls-green/lists"}