-
Notifications
You must be signed in to change notification settings - Fork 2
105 lines (89 loc) · 5.17 KB
/
Copy pathverify-changesets.yml
File metadata and controls
105 lines (89 loc) · 5.17 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
name: Verify Changesets
on:
workflow_call:
permissions:
contents: read
jobs:
verify-changesets:
name: "Verify changesets"
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- name: Setup Node.js and pnpm
uses: ./.github/actions/setup-node-pnpm
with:
install: "hardened"
- name: Test changeset and version-sync policies
run: pnpm run check:changesets
# A revert of a release commit restores MIGRATION.md, the consumed changesets and the pending
# migration fragments by construction, so it can never satisfy the rules below — the release
# reverts so far each needed an administrator bypass. The exemption is structural, never
# lexical: scripts/verify-revert.ts ignores the title and requires every commit the pull
# request adds to be the exact inverse, by patch id, of a commit already on the base.
- name: Detect a verified revert
id: revert
if: ${{ !github.event.pull_request.draft && github.event.pull_request.user.type != 'Bot' }}
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
run: node scripts/verify-revert.ts "$BASE_SHA" HEAD
- name: Check release-note presence
if: >-
${{ !github.event.pull_request.draft && github.event.pull_request.user.type != 'Bot'
&& steps.revert.outputs.verified-revert != 'true' }}
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
run: |
set -euo pipefail
# Image contents, excluding tests and in-tree documentation.
SHIPPED_PATHS=(
"server" "webapp" "docker"
":!**/*.md" ":!server/application/src/test" ":!webapp/e2e"
":!**/*.test.ts" ":!**/*.test.tsx" ":!**/*.stories.tsx"
)
# Compare from the merge base so only this PR's changes count.
shipped_changed=$(git diff --name-only "$BASE_SHA"...HEAD -- "${SHIPPED_PATHS[@]}")
mapfile -t changesets_added < <(git diff --diff-filter=A --name-only "$BASE_SHA"...HEAD -- '.changeset/*.md' | grep -v 'README\.md' || true)
mapfile -t changesets_changed < <(git diff --diff-filter=AM --name-only "$BASE_SHA"...HEAD -- '.changeset/*.md' | grep -v 'README\.md' || true)
mapfile -t changesets_removed < <(git diff --diff-filter=DR --name-only "$BASE_SHA"...HEAD -- '.changeset/*.md' | grep -v 'README\.md' || true)
mapfile -t migration_changed < <(git diff --diff-filter=AM --name-only "$BASE_SHA"...HEAD -- '.migration/*.md' | grep -v 'README\.md' || true)
mapfile -t migration_removed < <(git diff --diff-filter=DR --name-only "$BASE_SHA"...HEAD -- '.migration/*.md' | grep -v 'README\.md' || true)
if git diff --quiet "$BASE_SHA"...HEAD -- MIGRATION.md; then :; else
echo "::error::Do not edit MIGRATION.md in a feature PR; add a .migration/<changeset-slug>.md fragment instead."
exit 1
fi
if [ "${#migration_removed[@]}" -gt 0 ]; then
echo "::error::Pending migration fragments may be edited, but not deleted or renamed:"
printf '%s\n' "${migration_removed[@]}"
exit 1
fi
if [ "${#changesets_removed[@]}" -gt 0 ]; then
echo "::error::Pending changesets may be edited or converted to explained empty changesets, but not deleted or renamed:"
printf '%s\n' "${changesets_removed[@]}"
exit 1
fi
if [ "${#changesets_changed[@]}" -gt 0 ]; then
pnpm changeset status --since "$BASE_SHA" --output /tmp/changeset-status.json
node scripts/verify-changesets.ts /tmp/changeset-status.json "${changesets_changed[@]}"
fi
if [ "${#migration_changed[@]}" -gt 0 ]; then
# No --since here: a fragment may pair with a pending changeset merged by an earlier
# PR, and --since filters those out of the status output. Without --since the
# changesets CLI resolves its configured baseBranch by the exact ref name `main`,
# which a detached PR merge-ref checkout does not have — give it one.
git rev-parse --verify --quiet main >/dev/null || git branch main origin/main
pnpm changeset status --output /tmp/pending-changeset-status.json
node scripts/verify-changesets.ts /tmp/pending-changeset-status.json --migration "${migration_changed[@]}"
fi
if git diff --name-only "$BASE_SHA"...HEAD -- server/application/src/main/resources/db/changelog/ | grep -q .; then
echo "::notice::This PR contains Liquibase changesets — the release notes will flag the migration automatically. If the operator must act, add **Operators:** to its changeset and a matching .migration fragment."
fi
if [ -n "$shipped_changed" ] && [ "${#changesets_added[@]}" -eq 0 ]; then
echo "::error::This PR changes shipped code but carries no changeset:"
echo "$shipped_changed"
exit 1
fi
echo "Changeset check passed."