-
Notifications
You must be signed in to change notification settings - Fork 10
93 lines (83 loc) · 3.43 KB
/
Copy pathsync_version.yml
File metadata and controls
93 lines (83 loc) · 3.43 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
# Synchronizes the version in version.txt across the project files.
# Triggers on a push to version.txt on main, or manually.
name: Sync Version
on:
push:
paths:
- 'version.txt'
branches: ["main"]
workflow_dispatch:
# Deny by default. The one job below grants itself only what it needs.
permissions: {}
# A second push to version.txt while a run is in flight would race the first
# on the same branch name.
concurrency:
group: sync-version-${{ github.ref }}
cancel-in-progress: false
jobs:
sync-version:
runs-on: ubuntu-latest
permissions:
contents: write # create the version-sync branch
pull-requests: write # open the PR
steps:
- name: Check out the repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
version: "0.9.9"
- name: Read and validate version
id: version
run: |
set -euo pipefail
VERSION="$(tr -d '[:space:]' < version.txt)"
# version.txt is attacker-controlled by anyone with write access.
# Anything not matching semver stops here rather than reaching a
# shell, a git ref, or PR body markdown downstream.
if ! printf '%s' "$VERSION" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+([-+][0-9A-Za-z.-]+)?$'; then
echo "::error file=version.txt::Not a valid semantic version"
exit 1
fi
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "Validated version: ${VERSION}"
- name: Sync versions across files
env:
# Passed through the environment, never interpolated into the shell
# command. A ${{ }} expansion inside run: would execute as code.
VERSION: ${{ steps.version.outputs.version }}
run: |
set -euo pipefail
uv run .github/workflows/sync_version.py "$VERSION"
- name: Check for changes
id: changes
run: |
set -euo pipefail
if git diff --quiet; then
echo "has_changes=false" >> "$GITHUB_OUTPUT"
echo "No changes detected"
else
echo "has_changes=true" >> "$GITHUB_OUTPUT"
echo "Changes detected"
fi
- name: Create pull request
if: steps.changes.outputs.has_changes == 'true'
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "Automated: sync version to ${{ steps.version.outputs.version }}"
title: "Sync version to ${{ steps.version.outputs.version }}"
body: |
Synchronizes the release version in `pyproject.toml` to
`${{ steps.version.outputs.version }}`, read from `version.txt` and
validated as semver.
The specification version is deliberately not touched. It lives in
the schema `$id`, the `specification/v0.1.0/` directory name, and
the `$ref` links between those files. It moves only when the
specification changes, through a migration that renames the
directory and rewrites the references together.
branch: version-sync-${{ steps.version.outputs.version }}
delete-branch: true
sign-commits: true
add-paths: |
pyproject.toml