Automating the syncing of files between repos with GitHub Actions
As I wrote in Checking if files are synced between repos with GitHub Actions, if you're vendoring-and-periodically-updating files, trying to remember to do it is always a pain.
I've now decided to actually write a re-usable action that can be used to perform this work, prompted by a discussion around oapi-codegen, as the official project recommendation is to vendor files. Additionally, this is something that'll be useful at work (and with previous colleagues' setups too) so thought it'd be good to see how it'd be possible.
I've built this as a re-usable action so it's possible to reuse the same definition across multiple files (be they OpenAPI specs, Dependabot configuration or otherwise) as well as define rules around how often to update i.e. on every push, or on a schedule.
For instance, via the docs, we could use this for a multi-purpose Actions job that updates three files like so:
name: "Update OpenAPI specifications and raise PRs if changes needed"
permissions:
contents: write
# note that this also requires that GitHub Actions can raise PRs via steps in https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#preventing-github-actions-from-creating-or-approving-pull-requests
pull-requests: write
on:
schedule:
- cron: '30 5,17 * * *'
workflow_dispatch: {}
jobs:
sync-petstore:
uses: jamietanna/actions/.github/workflows/reusable-sync-file.yml@main
with:
identifier: oapi-codegen-petstore
remote_slug: deepmap/oapi-codegen
remote_path: examples/petstore-expanded/petstore-expanded.yaml
local_path: petstore.yaml
secrets:
# as this is a public repo, we can sync it easily with the inbuilt token
cross_repo_github_token: ${{ secrets.GITHUB_TOKEN }}
# and for a private repo that has two specs in it
sync-private-admin-api:
uses: jamietanna/actions/.github/workflows/reusable-sync-file.yml@main
with:
identifier: private-admin-api
remote_slug: jamietanna/example-github-actions-sync-files-private
remote_path: api/admin-api.yml
local_path: admin-api.yml
secrets:
# this requires a PAT
cross_repo_github_token: ${{ secrets.PAT }}
sync-private-another-api:
uses: jamietanna/actions/.github/workflows/reusable-sync-file.yml@main
with:
identifier: private-another-api
remote_slug: jamietanna/example-github-actions-sync-files-private
remote_path: api/another-api.yml
local_path: another-api.yml
secrets:
# this requires a PAT
cross_repo_github_token: ${{ secrets.PAT }}
Notice that we can wire in access tokens, as well as the relevant configuration for where to grab files from and update them in.
To see it in action, see an example PR for the Swagger Petstore API spec and a (fake) specification from a private repository.
When GitHub Actions runs, you can see job summaries i.e. to get the link to the created/updated PRs.
I hope that before long I'll get round to implementing this in Renovate but until then, this is a good solution.