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
148
149
150
151
152
153
154
155
name: CI
# Build, lint, and test on every pull request; on main this runs inside the
# release workflow (workflow_call), which gates release-please on it, so a main
# push gets exactly one CI run and a release can never cut from a red tree. The
# toolchain channel comes from rust-toolchain.toml. glslint shells out to
# glslangValidator (the Khronos GLSL reference compiler), so CI installs
# glslang-tools to exercise the real validation path.
#
# release-please's PR only bumps version strings + the changelog (no source, no
# workflows), and main is already CI-gated on every push via the workflow_call
# above, so re-running the whole suite on that PR is pure redundancy — yet its
# three jobs are required status checks, so the PR can't merge until they report.
# The catch: release-please authors that PR as github-actions[bot], and GitHub
# gates the pull_request run from a bot-authored PR behind manual approval, so it
# never starts, no check runs are created, and the required checks sit unreported
# forever. So release.yml stamps those three checks as skipped directly via the
# Checks API instead — only GitHub Apps can create check runs, and GITHUB_TOKEN
# is the Actions app's token, so the stamps satisfy the ruleset's app-pinned
# contexts, and a check whose conclusion is 'skipped' counts as passing, letting
# the release PR go green with no intervention. (Dispatching this workflow onto
# the release branch can't be trusted for that: the branch is only rebuilt when
# the changelog changes, so its copy of this file — and its workflow_dispatch
# trigger — can be stale.) The workflow_dispatch trigger and each job's skip
# guard below stay for manual runs: a job skips itself on the release-please
# branch (matched via head_ref on a PR run, or ref_name on a dispatched run),
# while on a workflow_call from a push the ref_name is 'main', so the full suite
# still runs on main. (If a fourth required check is ever added, give it the
# same guard.)
on:
pull_request:
workflow_call:
workflow_dispatch:
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
# Skip on release-please's PR (see header) — a skipped job counts as a
# passing required check, so the release PR merges without a full CI re-run.
# head_ref matches the PR run; ref_name the workflow_dispatch run.
if: ${{ !startsWith(github.head_ref, 'release-please--') && !startsWith(github.ref_name, 'release-please--') }}
runs-on: ubuntu-latest
timeout-minutes: 15
env:
RUSTC_WRAPPER: sccache
SCCACHE_GHA_ENABLED: "true"
CARGO_INCREMENTAL: "0"
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions-rust-lang/setup-rust-toolchain@166cdcfd11aee3cb47222f9ddb555ce30ddb9659 # v1.17.0
with:
components: clippy, rustfmt
cache: "false"
- uses: mozilla-actions/sccache-action@fc920bf0ec8de6ee65d409111f7ec508035751ba # v0.0.11
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
cache-targets: "false"
- name: Install glslang (provides glslangValidator)
run: sudo apt-get update && sudo apt-get install -y glslang-tools
- name: Format
run: cargo fmt --all --check
- name: Clippy
run: cargo clippy --all-targets --locked -- -D warnings
- name: Test
run: cargo test --locked
- name: sccache stats
if: ${{ always() }}
run: sccache --show-stats
npm:
# Exercise the npm distribution end to end: lay out the packages, then run
# the real binary through the wrapper's shim. Without this, a broken
# resolver or a platform table that has drifted from the wrapper's
# optionalDependencies would only surface after publishing.
if: ${{ !startsWith(github.head_ref, 'release-please--') && !startsWith(github.ref_name, 'release-please--') }}
runs-on: ubuntu-latest
timeout-minutes: 15
env:
RUSTC_WRAPPER: sccache
SCCACHE_GHA_ENABLED: "true"
CARGO_INCREMENTAL: "0"
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions-rust-lang/setup-rust-toolchain@166cdcfd11aee3cb47222f9ddb555ce30ddb9659 # v1.17.0
with:
cache: "false"
- uses: mozilla-actions/sccache-action@fc920bf0ec8de6ee65d409111f7ec508035751ba # v0.0.11
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
cache-targets: "false"
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 'lts/*'
- name: Check the drift guard without touching tracked files
run: node npm/prepare.mjs --version 0.0.0 --dry-run
# Same guard for the Homebrew formula: render it (with placeholder
# checksums) so a platform-table or template break surfaces on the PR, not
# at release time.
- name: Check the Homebrew formula renders
run: node homebrew/prepare.mjs --version 0.0.0 --dry-run
# The VS Code extension ships its own copy of the platform table (the .vsix
# can't read npm's at install time). Assert it still matches so the third
# hardcoded copy can't drift from the source of truth. This job's
# release-please branch skip (see header) covers this step too.
- name: Check the extension platform table matches
run: node editors/vscode/check-platforms.mjs
- name: Build
run: cargo build --locked
# One debug binary stands in for all four release assets: this checks the
# plumbing (layout, resolution, exec), not the cross-compiles.
- name: Stage it as the release assets
run: |
mkdir -p dist
for target in aarch64-apple-darwin x86_64-apple-darwin x86_64-unknown-linux-gnu; do
cp target/debug/glslint "dist/glslint-$target"
done
cp target/debug/glslint dist/glslint-x86_64-pc-windows-msvc.exe
- name: Lay out the packages
run: node npm/prepare.mjs --version 0.0.0 --binaries dist
# Resolve the linux-x64 package the way an install would, so the wrapper's
# require.resolve finds it by walking up to the repo root's node_modules.
- name: Link the platform package as an installed dependency
run: |
mkdir -p node_modules/@glslint
ln -s ../../npm/@glslint/linux-x64 node_modules/@glslint/linux-x64
- name: Run glslint through the npm shim
run: |
# Transparent passthrough: the shim must report exactly what the
# binary does, and mirror its exit status (no args is usage, exit 2).
test "$(node npm/glslint/bin/glslint.js --version)" = "$(target/debug/glslint --version)"
node npm/glslint/bin/glslint.js && code=0 || code=$?
test "$code" = 2
- name: sccache stats
if: ${{ always() }}
run: sccache --show-stats
deny:
if: ${{ !startsWith(github.head_ref, 'release-please--') && !startsWith(github.ref_name, 'release-please--') }}
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: EmbarkStudios/cargo-deny-action@3c6349835b2b7b196a839186cb8b78e02f7b5f25 # v2.1.1
with:
command: check advisories bans licenses sources