$ curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.64.7
go install mvdan.cc/gofumpt@latest
go install github.com/daixiang0/gci@latest
go run github.com/abcxyz/github-token-minter/cmd/minty@main \
private-key import \
-key=${KEY_NAME} \
-key-ring=${KEY_RING_NAME} \
-project-id=${PROJECT_ID} \
-private-key=@${KEY_FILE_NAME}
You need a GitHub App in your GitHub org.
To do this go to your org settings page: https://github.com/organizations/${YOUR_ORG}/settings/profile
- Expand Developer settings (last option on left sidebar) and click GitHub Apps.
- Click "New GitHub App" on top right.
- Give your App a name and Homepage URL (it doesn't matter what you have there).
- Note where "Webhook" is. Uncheck "Active" for now, we will configure later.
- Expand "Repository Permissions". Add following:
- Actions: Read-only
- Administration: Read and Write
- Metadata: Read-Only
- Expand "Organization Permissions". Add following:
- Administration: Read and Write # TODO: is this needed?
- Self-hosted runners: Read and Write
- Click "Create GitHub App" at bottom of screen.
- Find your app listed in Developer Settings in your org settings page.
- Take note of App ID
- Click Edit
- Scroll down to almost the bottom for "Private Keys"
- Click "Generate a private key"
- A .pem file will be downloaded. This is a secret. Keep it safe.
Now that the GitHub App exists, it needs to be added to your org.
- Navigate to Org setting page https://github.com/organizations/${YOUR_ORG}/settings/profile
- Expand Developer settings (last option on left sidebar) and click GitHub Apps.
- Select Your App
- On the left bar, select "Install App"
- Select your org.
Prereqs: Sudoless docker installed. Not currently set up to work with GitHub Enterprise Server.
Now we have an app and a .pem key, we should be able to create JIT configs. These are one-time tokens that allow a runner to register itself with GitHub.
test_local.sh
is set up for this. You just need to change a few values in
the go run
command under # Generate JIT Config
:
- Set app-id to the app id found in Step 8. of GitHub App Creation.
- Set
private-key
to the path of your.pem
file you downloaded. - Set
org
to the name of your GitHub org. - Set
runner-group-id
to the value of your runner group. You can just use1
which is the default runner group added to each org.
Now run the script. You should see it build the image, then see output for runner startup and finally see it waiting for a request.
If this doesn't happen, something went wrong, you should figure it out before continuing.
TODO
The project has two main components that are deployed independently: the webhook and the runner.
The webhook is a containerized application that receives workflow_job
events from GitHub.
-
Continuous Integration & Build: On every push to the
main
branch, thebuild_webhook_container
workflow is triggered. This workflow builds a Docker image for the webhook and tags it with the commit SHA. The image is then pushed to Google Artifact Registry. -
Autopush Environment: After a successful build on the
main
branch, theautopush_webhook_container
workflow automatically deploys the newly built container image to an "autopush" environment. This provides a way to test changes in a live environment before a production deployment. -
Production Deployment: Production deployments are manual and triggered via the
Promote to Production
workflow. This workflow requires animage_tag
(the commit SHA of the version to be deployed) as input. It then updates the production Cloud Run service to use the specified image.
The runner is a containerized application that executes the GitHub Actions jobs.
-
Continuous Integration & Build: The
build_runner_container
workflow builds the runner Docker image and pushes it to Google Artifact Registry with thelatest
tag. This workflow is triggered on pushes to themain
branch that include changes in therunner/
directory. -
Deployment: There is no separate deployment process for the runner. The webhook is configured to dynamically pull and use the
latest
tag of the runner image from the Artifact Registry at runtime. This means that once a new runner image is pushed, newly created runners will automatically use the updated version without any manual intervention.
The CI/CD pipeline for this project includes a workflow to test pull requests that modify the webhook. This workflow deploys a temporary, isolated instance of the webhook to the autopush
environment and runs a series of tests against it.
To enable secure end-to-end testing, a dedicated webhook secret named webhook-pr-test-secret
is used. This secret is managed as a permanent resource in the google-infra-gcp
repository and is stored in Google Cloud Secret Manager in the action-dispatcher-webhook-a-18
project.
The github-automation-bot
service account has the roles/secretmanager.secretAccessor
permission for this secret, allowing the CI/CD pipeline to fetch it and use it to sign mock webhook payloads.
If this secret needs to be rotated, follow these steps:
-
Generate a new secret value:
openssl rand -hex 32
-
Add the new value as a new version to the existing secret: You must have the
secretmanager.secretVersionAdder
IAM role on theaction-dispatcher-webhook-a-18
project to perform this action.printf "YOUR_NEW_SECRET_VALUE\n" | gcloud secrets versions add "webhook-pr-test-secret" --data-file=- --project="action-dispatcher-webhook-a-18"
-
The CI/CD workflow will automatically pick up the
latest
version of the secret.