-
Notifications
You must be signed in to change notification settings - Fork 416
135 lines (126 loc) · 5.92 KB
/
Copy pathaction-version-bump.yml
File metadata and controls
135 lines (126 loc) · 5.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
name: Action Version Bump
# Guards the GitHub Action's independent release cadence (AGENTS.md → "GitHub
# Action versioning"). When a change touches the action's release surface
# (action.yml + the scripts it shells out to), this either recommends a version
# bump on the PR or — opt-in — performs it on merge to main.
on:
pull_request:
branches: [main]
types: [opened, synchronize, reopened, edited]
push:
branches: [main]
permissions:
contents: read
jobs:
recommend:
name: Recommend bump on PR
if: ${{ github.event_name == 'pull_request' }}
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v5
with:
persist-credentials: false
fetch-depth: 0
fetch-tags: true
- name: Detect action changes and compute recommended bump
id: detect
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
ACTION_COMMIT_SUBJECT: ${{ github.event.pull_request.title }}
run: |
export ACTION_CHANGED_FILES="$(git diff --name-only "${BASE_SHA}...${HEAD_SHA}")"
export ACTION_ALL_TAGS="$(git tag --list 'v*')"
node scripts/recommend-action-version-bump.mjs "${RUNNER_TEMP}/action-version-comment.md"
- name: Upsert recommendation comment
uses: actions/github-script@v7
env:
ACTION_CHANGED: ${{ steps.detect.outputs.changed }}
COMMENT_FILE: ${{ runner.temp }}/action-version-comment.md
with:
script: |
const fs = require("node:fs");
const marker = "<!-- react-doctor:action-version -->";
const { owner, repo } = context.repo;
const issueNumber = context.payload.pull_request.number;
const comments = await github.paginate(github.rest.issues.listComments, {
owner,
repo,
issue_number: issueNumber,
});
const existing = comments.find((comment) => comment.body?.includes(marker));
if (process.env.ACTION_CHANGED !== "true") {
// The PR no longer touches the action surface — clear a stale recommendation.
if (existing) {
await github.rest.issues.deleteComment({ owner, repo, comment_id: existing.id });
}
return;
}
const body = fs.readFileSync(process.env.COMMENT_FILE, "utf8");
if (existing) {
await github.rest.issues.updateComment({ owner, repo, comment_id: existing.id, body });
} else {
await github.rest.issues.createComment({ owner, repo, issue_number: issueNumber, body });
}
bump:
name: Perform bump on merge
# Opt-in: set the repo variable AUTO_BUMP_ACTION_TAG=true to auto-tag.
# Otherwise this is a no-op and the maintainer cuts the GPG-signed tag by
# hand using the commands from the PR recommendation.
if: ${{ github.event_name == 'push' && vars.AUTO_BUMP_ACTION_TAG == 'true' }}
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: write
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
fetch-tags: true
- name: Detect action changes and compute recommended bump
id: detect
env:
GH_TOKEN: ${{ github.token }}
BEFORE_SHA: ${{ github.event.before }}
HEAD_COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
run: |
base="${BEFORE_SHA}"
if [ -z "${base}" ] || [ "${base}" = "0000000000000000000000000000000000000000" ]; then
# New branch / first push: diff against HEAD's parent, or the empty
# tree for a root commit with no parent (so its files still count as
# changed instead of diffing HEAD against itself).
base="$(git rev-parse HEAD^ 2>/dev/null || git hash-object -t tree /dev/null)"
fi
# Classify from the merged PR's title — the same authoritative signal the
# recommend job uses — so a non-conventional merge subject (e.g.
# "Merge pull request #N") can't silently downgrade the bump to a patch.
# Fall back to the commit subject for a direct push to main.
pr_title="$(gh api "repos/${GITHUB_REPOSITORY}/commits/${GITHUB_SHA}/pulls" --jq '.[0].title // ""' 2>/dev/null || true)"
if [ -n "${pr_title}" ]; then
export ACTION_COMMIT_SUBJECT="${pr_title}"
else
export ACTION_COMMIT_SUBJECT="$(printf '%s' "${HEAD_COMMIT_MESSAGE}" | head -n1)"
fi
export ACTION_CHANGED_FILES="$(git diff --name-only "${base}" "${GITHUB_SHA}")"
export ACTION_ALL_TAGS="$(git tag --list 'v*')"
node scripts/recommend-action-version-bump.mjs
- name: Create and push action release tags
if: ${{ steps.detect.outputs.changed == 'true' && steps.detect.outputs['tag-exists'] != 'true' }}
env:
NEXT_TAG: ${{ steps.detect.outputs.next }}
MAJOR_TAG: ${{ steps.detect.outputs.major }}
BUMP_LEVEL: ${{ steps.detect.outputs.level }}
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
# CI has no signing key, so override the repo's tag.gpgsign default and
# create an unsigned annotated tag instead of failing on a missing key.
git -c tag.gpgsign=false tag -a "${NEXT_TAG}" -m "react-doctor action ${NEXT_TAG} (${BUMP_LEVEL})"
git -c tag.gpgsign=false tag -fa "${MAJOR_TAG}" -m "react-doctor action ${MAJOR_TAG} (floating major -> ${NEXT_TAG})"
git push origin "${NEXT_TAG}"
git push --force origin "${MAJOR_TAG}"
echo "Tagged ${NEXT_TAG} and moved ${MAJOR_TAG} to ${GITHUB_SHA}." >> "${GITHUB_STEP_SUMMARY}"