-
Notifications
You must be signed in to change notification settings - Fork 0
147 lines (127 loc) · 5.7 KB
/
Copy pathupdate-rustcfml.yml
File metadata and controls
147 lines (127 loc) · 5.7 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
136
137
138
139
140
141
142
143
144
145
146
147
name: Update RustCFML
# Follows the engine's current STABLE release and rebuilds the site on it.
#
# Adapted from the worker host's workflow of the same name, which learned two
# things the hard way:
#
# * Do not follow upstream TAGS. Every RustCFML version tag is published as a
# prerelease and a human promotes one to stable, so following tags meant a
# bump per patch release — a dozen in two days. `gh release view` resolves
# the promoted one.
# * Do not open a pull request. One superseded PR per release, none merged, is
# how a dependency ends up six versions behind. The build gate is what makes
# a PR unnecessary: wasm32 must compile against the new engine before
# anything is committed, and a failure leaves main untouched.
#
# What it bumps, and why both: Cargo.toml pins the engine the Worker runs, and
# Application.cfc's `this.version` drives the footer and every download link.
# Before this existed those two drifted 30 releases apart, because the
# tools/set-version.py the README points at is not in the repository.
#
# Mechanism: scheduled poll, so nothing is needed in the RustCFML repo.
on:
schedule:
- cron: "0 * * * *"
workflow_dispatch: {}
permissions:
contents: write
env:
UPSTREAM_REPO: RustCFML/RustCFML
jobs:
update:
runs-on: ubuntu-latest
outputs:
changed: ${{ steps.versions.outputs.changed }}
latest: ${{ steps.versions.outputs.latest }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }}
- name: Determine current and latest versions
id: versions
env:
GH_TOKEN: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
current="$(grep -oP 'cfml-worker\s*=.*tag\s*=\s*"\K[^"]+' Cargo.toml)"
site="$(grep -oP 'this\.version\s*=\s*"\K[^"]+' Application.cfc)"
echo "Worker pins: $current"
echo "Site quotes: $site"
# GitHub's "latest release" excludes prereleases, which is exactly the
# promoted-to-stable one.
latest="$(gh release view --repo "${UPSTREAM_REPO}" --json tagName --jq .tagName)"
echo "Latest stable: $latest"
[ -n "$latest" ] || { echo "::error::no stable release found"; exit 1; }
{
echo "current=$current"
echo "latest=$latest"
} >> "$GITHUB_OUTPUT"
# Rebuild when either file is behind: the site version can lag even
# when the worker pin does not.
if [ "$current" = "$latest" ] && [ "$site" = "$latest" ]; then
echo "Already on $latest. Nothing to do."
echo "changed=false" >> "$GITHUB_OUTPUT"
elif [ "$(printf '%s\n%s\n' "$current" "$latest" | sort -V | tail -n1)" != "$latest" ]; then
echo "Pinned $current is newer than the latest stable $latest. Leaving it alone."
echo "changed=false" >> "$GITHUB_OUTPUT"
else
echo "changed=true" >> "$GITHUB_OUTPUT"
fi
- name: Set up Rust (wasm32)
if: steps.versions.outputs.changed == 'true'
run: |
set -euo pipefail
rustup toolchain install stable --profile minimal
rustup target add wasm32-unknown-unknown
- name: Cache cargo
if: steps.versions.outputs.changed == 'true'
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: cargo-${{ runner.os }}-${{ hashFiles('Cargo.lock') }}
restore-keys: |
cargo-${{ runner.os }}-
- name: Bump both files and verify the build
if: steps.versions.outputs.changed == 'true'
env:
CURRENT: ${{ steps.versions.outputs.current }}
LATEST: ${{ steps.versions.outputs.latest }}
run: |
set -euo pipefail
sed -i "s|tag = \"${CURRENT}\"|tag = \"${LATEST}\"|" Cargo.toml
sed -i "s|this\.version = \"[^\"]*\"|this.version = \"${LATEST}\"|" Application.cfc
# Prove both edits landed: a sed pattern that matches nothing still
# exits 0, and the run would commit a bump that never happened.
grep -q "tag = \"${LATEST}\"" Cargo.toml \
|| { echo "::error::Cargo.toml does not pin ${LATEST}"; exit 1; }
grep -q "this.version = \"${LATEST}\"" Application.cfc \
|| { echo "::error::Application.cfc does not quote ${LATEST}"; exit 1; }
cargo update -p cfml-worker --precise "${LATEST}"
# The gate that makes committing without review safe.
cargo build --release --target wasm32-unknown-unknown
- name: Commit to main
if: steps.versions.outputs.changed == 'true'
env:
CURRENT: ${{ steps.versions.outputs.current }}
LATEST: ${{ steps.versions.outputs.latest }}
run: |
set -euo pipefail
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add Cargo.toml Cargo.lock Application.cfc
git commit -m "Rebuild on RustCFML ${LATEST} (was ${CURRENT})
${LATEST} was promoted to stable upstream. The Worker's engine pin and
the version the site quotes are bumped together, and wasm32 compiled
against the new engine in CI before this was committed."
git push origin "HEAD:${{ github.ref_name }}"
# Called directly rather than left to the push above: a push authenticated
# with GITHUB_TOKEN does not trigger `on: push` workflows.
deploy:
needs: update
if: needs.update.outputs.changed == 'true'
uses: ./.github/workflows/deploy.yml
secrets: inherit