{"id":37109484,"url":"https://github.com/lewagon/quay-github-actions-dispatch","last_synced_at":"2026-01-14T13:01:07.946Z","repository":{"id":75249639,"uuid":"254113200","full_name":"lewagon/quay-github-actions-dispatch","owner":"lewagon","description":"A missing *secure* link between Quay.io build triggers and Github Action's repository_dispatch events","archived":true,"fork":false,"pushed_at":"2020-04-10T12:13:03.000Z","size":35,"stargazers_count":7,"open_issues_count":0,"forks_count":1,"subscribers_count":10,"default_branch":"master","last_synced_at":"2023-08-06T10:11:54.509Z","etag":null,"topics":["cd","ci","devops","docker","github-actions","golang","quay"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lewagon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2020-04-08T14:36:39.000Z","updated_at":"2024-06-19T06:36:25.644Z","dependencies_parsed_at":"2023-06-05T20:45:33.199Z","dependency_job_id":null,"html_url":"https://github.com/lewagon/quay-github-actions-dispatch","commit_stats":null,"previous_names":[],"tags_count":0,"template":null,"template_full_name":null,"purl":"pkg:github/lewagon/quay-github-actions-dispatch","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lewagon%2Fquay-github-actions-dispatch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lewagon%2Fquay-github-actions-dispatch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lewagon%2Fquay-github-actions-dispatch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lewagon%2Fquay-github-actions-dispatch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lewagon","download_url":"https://codeload.github.com/lewagon/quay-github-actions-dispatch/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lewagon%2Fquay-github-actions-dispatch/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28420816,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T10:47:48.104Z","status":"ssl_error","status_checked_at":"2026-01-14T10:46:19.031Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["cd","ci","devops","docker","github-actions","golang","quay"],"created_at":"2026-01-14T13:01:07.135Z","updated_at":"2026-01-14T13:01:07.889Z","avatar_url":"https://github.com/lewagon.png","language":"Go","readme":"# Quay Github Actions Dispatch\n\nA mini-service for securely forwarding Quay [build notifications](https://docs.quay.io/guides/notifications.html) to Github Actions' [obscure](https://help.github.com/en/actions/reference/events-that-trigger-workflows#external-events-repository_dispatch) `repository_dispatch` webhook to trigger any workflow in your repository _remotely_ as a \"callback\" on successful image build.\n\nIt combines the speed and caching efficiency of Quay.io for building your production Docker images with the _\"I don't ever need another CI/CD tool\"_ promise of Github Actions.\n\nHere's how it works:\n\n```\n+-------------+                                      +---------+\n| GitHub Repo +--------+build trigger👷‍+------------\u003e+ Quay.io |\n+------+------+                                      +-----+---+\n       ^                                                   |\n       |                                                   |\n       |                                                   |\n       |                                      Webhook      |\n       |                                      success      |\n       |  Triggers                            notification |\n       |  Github Actions                      over HTTPS   |\n       |  workflow👌                                       |\n       |                                                   |\n       |               +-----------------+                 |\n       +---------------+ This service :) +\u003c----------------+\n                       +-----------------+\n\n                        Verifies authenticity\n                        through Quay's SSL cert 🔑\n```\n\n\n## Usage\n\n### Running your own quay-github-actions-dispatch endpoint\n\nIt is recommended to run this service on a dedicated VPS with **no load balancer or reverse proxy** and an open 443 port.\nYou should also obtain a certificate for a _domain name you will put your endpoint_ on as Quay needs to send you a webhook over HTTPS (otherwise you will not be able to authenticate through SSL) and point this domain name to your VPS' IP address.\n\n:warning: `quay-github-actions-dispatch` performs it's own SSL termination to read Quay's certificate and it needs access to relevant `.pem` and `.key` files.\n\nOn the server with a 443 port exposed and certificates for domain name set up:\n\n```sh\n docker run -d --rm -p 443:443 \\\n -v /certs:/certs \\                # /certs folder on your host needs to have .key and .pem files\n -e GH_TOKEN=YOUR_GITHUB_TOKEN \\   # token needs only `repo:read` access\n -e DEBUG=true \\                  # optional to log incoming and outgoing requests and responses\n lewagon/quay-github-actions-dispatch:0.2\n```\nIn your Quay repository settings, under \"Events and Notifications\" create a \"Webhook POST\" notification for \"Dockerfile Build Successfully Completed\" and provide `https://YOUR_CERTIFIED_DOMAIN.com/incoming` endpoint.\n\n### Incoming payload\n\n```json\n{\n  \"build_id\": \"fake-build-id\",\n  \"trigger_kind\": \"GitHub\",\n  \"name\": \"your_repo_name\",\n  \"repository\": \"your_github/your_repo_name\",\n  \"namespace\": \"your_repo_name\",\n  \"docker_url\": \"quay.io/your_github/your_repo_name\",\n  \"trigger_id\": \"1245634\",\n  \"docker_tags\": [\n    \"latest\",\n    \"foo\",\n    \"bar\"\n  ],\n  \"build_name\": \"some-fake-build\",\n  \"image_id\": \"1245657346\",\n  \"trigger_metadata\": {\n    \"default_branch\": \"master\",\n    \"ref\": \"refs/heads/somebranch\",\n    \"commit\": \"42d4a62c53350993ea41069e9f2cfdefb0df097d\"\n  },\n  \"homepage\": \"https://quay.io/your_github/your_repo_name/your_repo_name/build/fake-build-id\"\n}\n```\n\n### Outgoing payload\n\nWill be sent to `https://api.github.com/repos/your_github/your_repo/dispatches`\n\n```json\n{\n  \"event_type\": \"QUAY_BUILD_SUCCESS\",\n  \"client_payload\": {\n    \"text\": \"42d4a62\"\n  }\n}\n```\n\n`\"text\"` field will contain first 7 chars of your commit SHA from the incoming payload\n\nThe service wil also set the headers that Github requires: \n\n```\nAuthorization: token your-token-here\nAccept: application/vnd.github.everest-preview+json\n```\n\nToken will be read from the ENV variable `GH_TOKEN` that you can set to your GitHub token value with the `repo:read` scope.\n\n### Workflow example to trigger on QUAY_BUILD_SUCCESS event\n\nDeploy to Digital Ocean managed Kubernetes with Helm 3\n\n```yml\nname: Helm deploy all things\non:\n  repository_dispatch:\n    types: [QUAY_BUILD_SUCCESS]\n\njobs:\n  build:\n    if: startsWith(github.sha, github.event.client_payload.text)\n    name: Helm update\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@master\n\n      - name: Save DigitalOcean kubeconfig\n        uses: digitalocean/action-doctl@master\n        env:\n          DIGITALOCEAN_ACCESS_TOKEN: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}\n        with:\n          args: kubernetes cluster kubeconfig show CLUSTER_NAME \u003e $GITHUB_WORKSPACE/.kubeconfig\n\n      - name: Upgrade/install chart\n        run: |\n        export KUBECONFIG=$GITHUB_WORKSPACE/.kubeconfig \u0026\u0026 \\\n        helm upgrade your_release charts/chart_name --install \\\n        --atomic --cleanup-on-fail \\\n        --set-string image.tag=$(echo $GITHUB_SHA | head -c7) \\\n```\n\n## Why?\n\n* Containers are awesome. Kubernetes makes them even more awesome.\n* Github Actions are awesome, but it's not possible to cache Docker builds, so bigger production images can take long (10 mins+) to build.\n* Quay is awesome: easy to trigger a build from a push to any branch on GitHub and label an image either with a branch name or a commit SHA. Builds are cached and it takes very little time to build a new image, if the only layer changed is your `COPY . /myawesomeapp`. There is even a possibility to send a POST request to any webhook if the build has started/succeeded/failed. However, there is no control over headers or a body of that POST request.\n* Github Actions workflows can be triggered by the external [repository_dispatch](https://help.github.com/en/actions/reference/events-that-trigger-workflows#external-events-repository_dispatch) event, but GitHub HTTP API  expects very certain payload with very certain headers.\n* Imagine the world where Quay could send a webhook POST directly to GitHub and trigger a workflow in your repo if the image was successfully built.\n\n`quay-github-actions-dispatch` is exactly that :point_up: missing link.\n\n## How\n\nEasy, you think, just let me code an endpoint that receives a webhook payload from Quay and transforms it into a webhook request for GitHub.\n\n_Not so fast!_\n\nQuay notifications bare no authentication, so _anyone_ simulating the Quay payload could trigger events directly in your repo and this is definitely not what you want. However:\n\n\u003e When the URL is HTTPS, the call will have an SSL client certificate set from Quay.io. Verification of this certificate will prove the call originated from Quay.io. —Quay.io Repository Notifications [Manual](https://docs.quay.io/guides/notifications.html)\n\nThis is exactly what `quay-github-actions-dispatch` does: **verifies that Quay is indeed Quay by looking at it's TLS peer certificate**\n\n## Build your own Docker image from source\n\nUse latest versions of Go with built-in [modules](https://github.com/golang/go/wiki/Modules#example) support\n\n```sh\ngit clone git@github.com:lewagon/quay-github-actions-dispatch.git\ncd quay-github-actions-dispatch\nGOOS=linux GOARCH=amd64 go build .  # assuming you use a Linux server\ndocker build -t IMAGE:TAG .\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flewagon%2Fquay-github-actions-dispatch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flewagon%2Fquay-github-actions-dispatch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flewagon%2Fquay-github-actions-dispatch/lists"}