Skip to content

Commit d57390b

Browse files
committed
Add GH Action workflow to update downstream repos
Searches the Nextstrain GitHub org to find repos that have the `.gitrepo` file with the nextstrain/shared remote to create a matrix of repos to potentially update. Installs and uses `git subrepo` to pull in the latest changes with the `--force` flag to avoid merge conflicts to due rebasing in the downstream repo. If there are changes pulled down, then `git subrepo` will create a single commit. If there is a single commit, then push up the changes to a branch and create or update the PR in the downstream repo. Nothing happens if there were no changes and workflow exits with error if it encounters more than one commit.
1 parent c29898f commit d57390b

1 file changed

Lines changed: 102 additions & 0 deletions

File tree

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
name: Update downstream repos
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
workflow_dispatch:
8+
9+
concurrency:
10+
group: ${{ github.workflow }}
11+
cancel-in-progress: true
12+
13+
jobs:
14+
build-downstream-matrix:
15+
runs-on: ubuntu-latest
16+
outputs:
17+
downstream-matrix: ${{ steps.downstream-matrix.outputs.downstream-matrix }}
18+
steps:
19+
- id: downstream-matrix
20+
env:
21+
GH_TOKEN: ${{ secrets.GH_TOKEN_NEXTSTRAIN_BOT_REPO }}
22+
# Create an array of potential repos to update that will be used as the
23+
# matrix to the next job.
24+
# [
25+
# { "repo": "nextstrain/zika", "path": "shared/vendored"},
26+
# { "repo": "nextstrain/mpox", "path": "shared/vendored"},
27+
# ...
28+
# ]
29+
run: |
30+
matrix=$(gh api -X GET search/code \
31+
-f q='org:nextstrain filename:.gitrepo "remote = https://github.com/nextstrain/shared"' \
32+
| jq -c '
33+
.items
34+
| map({
35+
"repo": "\(.repository.full_name)",
36+
"path": "\(.path | split("/")[0:-1] | join("/"))"
37+
})
38+
')
39+
echo "downstream-matrix=$matrix" | tee -a "$GITHUB_OUTPUT"
40+
update-downstream:
41+
name: update-downstream (${{ matrix.repo }}, ${{ matrix.path }})
42+
needs: [build-downstream-matrix]
43+
strategy:
44+
fail-fast: false
45+
matrix:
46+
include: ${{ fromJson(needs.build-downstream-matrix.outputs.downstream-matrix) }}
47+
env:
48+
GIT_SUBREPO_DIR: .git/git-subrepo
49+
VENDORED_PATH: ${{ matrix.path }}
50+
branch: nextstrain-bot/update-vendored
51+
runs-on: ubuntu-latest
52+
steps:
53+
- name: Checkout ${{ matrix.repo }}
54+
uses: actions/checkout@v6
55+
with:
56+
repository: ${{ matrix.repo }}
57+
token: ${{ secrets.GH_TOKEN_NEXTSTRAIN_BOT_REPO }}
58+
# Checkout git-subrepo _after_ the downstream repo to ensure that we
59+
# keep it in a path within the downstream repo that does not interefere
60+
# with the subrepo changes
61+
- name: Checkout git-subrepo
62+
uses: actions/checkout@v6
63+
with:
64+
repository: "ingydotnet/git-subrepo"
65+
path: ${{ env.GIT_SUBREPO_DIR }}
66+
- name: Add git-subrepo to PATH
67+
run: echo "$GIT_SUBREPO_DIR/lib" >> "$GITHUB_PATH"
68+
- name: Update vendored path
69+
run: |
70+
git config user.name "${{ vars.GIT_USER_NAME_NEXTSTRAIN_BOT }}"
71+
git config user.email "${{ vars.GIT_USER_EMAIL_NEXTSTRAIN_BOT }}"
72+
73+
git switch -c "$branch"
74+
git subrepo pull "$VENDORED_PATH" --force
75+
- name: Create pull request
76+
env:
77+
GH_TOKEN: ${{ secrets.GH_TOKEN_NEXTSTRAIN_BOT_REPO }}
78+
title: '[bot] Update ${{ env.VENDORED_PATH }}'
79+
body: |
80+
This PR was automaticaly created by http://github.com/nextstrain/shared/actions/runs/${{ github.run_id }}
81+
to update the vendored subrepo in ${{ env.VENDORED_PATH }}.
82+
83+
Subrepo updates were made with the `--force` flag so it overwrites any local changes in the subrepo.
84+
run: |
85+
default_branch=$(git remote show origin | sed -n '/HEAD branch/s/.*: //p')
86+
changes=$(git rev-list --count "$default_branch".."$branch")
87+
if [[ "$changes" == "1" ]]; then
88+
git push --force origin HEAD
89+
pr_url=$(gh pr list --head "$branch" --json url | jq -r '.[0].url')
90+
91+
if [[ "$pr_url" == "null" ]]; then
92+
pr_url="$(gh pr create --head "$branch" --title "$title" --body "$body")"
93+
echo "Pull request created: $pr_url" >> "$GITHUB_STEP_SUMMARY"
94+
else
95+
echo "Pull request updated: $pr_url" >> "$GITHUB_STEP_SUMMARY"
96+
fi
97+
elif [[ "$changes" == "0" ]]; then
98+
echo "No pull request created or updated because no changes were made" >> "$GITHUB_STEP_SUMMARY"
99+
else
100+
echo "ERROR: Encountered an unexpected number of changes: $changes"
101+
exit 1
102+
fi

0 commit comments

Comments
 (0)