Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Workflow naming

One rule: **the filename is the identity, and `name:` is its Title Case
rendering.** Either can be derived from the other.

```
<subject>[-<qualifier>].yml
```

Subject first, always — including for release and publish workflows. Product
identifiers keep their own spelling (`didc`, `candid_ui`).

| file | `name:` | |
|---|---|---|
| `candid-ui-release.yml` | Candid UI Release | |
| `coq.yml` | Coq | removed once `lean/` covers it |
| `crates-publish.yml` | Crates Publish | |
| `dependencies.yml` | Dependencies | licenses, bans and sources via cargo-deny |
| `didc-release.yml` | Release | generated — see below |
| `rust-bench.yml` | Rust Bench | |
| `rust.yml` | Rust | removed once `crates/` replaces it |
| `tools.yml` | Tools | |

Subject-first is what groups related workflows together (`rust.yml` /
`rust-bench.yml`, `crates.yml` / `crates-publish.yml`) and it is what
`didc-release.yml` forces, so there is one pattern rather than one pattern plus
an exception.

## Jobs

- Job ids are kebab-case.
- **Omit `name:`** unless it says something the id does not — GitHub falls back
to the id, so a `name:` that repeats it is duplicated state.
- The check name is what appears in a list of a dozen-plus entries on a pull
request, so it has to stand alone. `coq` works; `build` does not.
- **No `:required` suffix.** GitHub already labels required checks in the merge
box. Encoding it in the name duplicates settings that live elsewhere, and it
drifted the last time it was tried — the marker sat on `license-check`, which
was not required, while `rust`, which is, never carried it.

## Required checks

`rust` is the only required status check, and it is an **aggregate job** at the
bottom of `rust.yml` rather than a job that does work. It `needs:` the real jobs
and fails if any of them did. The same shape as `test:required` in
[icp-cli](https://github.com/dfinity/icp-cli)'s `test.yml`.

Two properties make it worth the extra job:

- It runs under `if: always()` with no condition, so it reports on every pull
request — including ones where every job it watches was skipped. The required
check therefore never depends on how GitHub scores a *skipped* job. (icp-cli's
aggregate is additionally gated on its paths filter, so it does still rely on
that; ours deliberately is not.)
- New work jobs are added to its `needs:` list and gate merging immediately, with
no branch protection change. Only one context is ever configured.

It treats `skipped` as a pass, since that means the paths filter ruled the job
out. It does not gate on the `changes` job: the work jobs fall open when
detection fails, so the work still ran, and `detect changes` going red is the
signal on its own.

`rust.yml` must not use a workflow-level `paths:` filter — see the comment at the
top of that file.

Workflows added for the rewrite (`crates`, `lean`, `conformance`) should **not**
be required. [REWRITE.md](../../REWRITE.md) depends on work in those directories
being allowed to be broken; making their checks gate merges would contradict it.
Promote them individually at v1 by adding an aggregate of their own.

## `didc-release.yml` is generated

It is written by [dist](https://opensource.axo.dev/cargo-dist/) from
[`dist-workspace.toml`](../../dist-workspace.toml). Do not edit it; run
`dist generate` after changing that config.

Two things follow:

- The **filename** comes from `tag-namespace`, which is also the release tag
prefix (`didc-vX.Y.Z`). `tag-namespace = "didc"` produces
`didc-release.yml`. It cannot be set independently of the tag scheme.
- The **`name:` field** is not configurable at all; dist always emits
`name: Release`. This is the one place the filename/`name:` mapping above does
not hold.
59 changes: 0 additions & 59 deletions .github/workflows/bench.yml

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Release candid_ui
name: Candid UI Release

# The candid_ui canister wasm is released on the repo's date-based tags
# (e.g. 2025-12-18). The didc binaries are released separately by
Expand All @@ -12,7 +12,6 @@ on:

jobs:
candid-ui:
name: Build and publish candid_ui canister
runs-on: ubuntu-22.04
permissions:
contents: write
Expand All @@ -22,8 +21,11 @@ jobs:
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: '20'
- name: Remove pre-installed Rust stable toolchain
run: rustup toolchain remove stable 2>/dev/null || true
# rust-toolchain.toml supplies the channel and the wasm32 target.
- name: Install Rust toolchain
run: rustup show active-toolchain || rustup toolchain install
uses: actions-rust-lang/setup-rust-toolchain@150fca883cd4034361b621bd4e6a9d34e5143606 # v1.15.4
- name: Install binaryen
run: |
sudo apt-get update -yy
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/coq.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:
- 'coq/**'

jobs:
build:
coq:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Publish crates to crates.io
name: Crates Publish

on:
workflow_dispatch:
Expand All @@ -18,7 +18,6 @@ on:

jobs:
publish:
name: Publish selected crates
runs-on: ubuntu-24.04
if: >-
inputs.ic_principal || inputs.candid || inputs.candid_parser
Expand Down
30 changes: 30 additions & 0 deletions .github/workflows/dependencies.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Dependencies

on:
push:
branches:
- master
pull_request:
# Findings can only change when the dependency graph or the policy does.
paths:
- '**/Cargo.toml'
- '**/Cargo.lock'
- 'deny.toml'
- '.github/workflows/dependencies.yml'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
cargo-deny:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# cargo-deny only reads the dependency graph; dropping the pin avoids
# installing a toolchain and the wasm32 target it would pull in.
- run: rm rust-toolchain.toml
- uses: EmbarkStudios/cargo-deny-action@3fd3802e88374d3fe9159b834c7714ec57d6c979 # v2.0.15
with:
# advisories are not covered here — candid has no RUSTSEC scanning yet
command: check bans licenses sources
21 changes: 0 additions & 21 deletions .github/workflows/license.yml

This file was deleted.

102 changes: 102 additions & 0 deletions .github/workflows/rust-bench.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
name: Rust Bench

on:
pull_request:
paths:
- 'rust/**'
- 'Cargo.toml'
- 'Cargo.lock'
- 'rust-toolchain.toml'
- '.github/workflows/rust-bench.yml'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

# Runs benchmark code from the pull request, so it must never hold a writable
# token. The report goes to the job summary, which needs no token at all.
permissions:
contents: read

env:
CARGO_TERM_COLOR: always # Force Cargo to use colors
TERM: xterm-256color
CANBENCH_VERSION: 0.2.0
# Fail the job when an instruction count regresses by more than this.
REGRESSION_THRESHOLD_PERCENT: 10

jobs:
bench:
runs-on: ubuntu-24.04
steps:
- name: Checkout pull request
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Checkout base branch
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.base_ref }}
path: main/
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.10"
- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
pip install pyyaml
- name: Remove pre-installed Rust stable toolchain
run: rustup toolchain remove stable 2>/dev/null || true
# No explicit `toolchain` — uses the channel from rust-toolchain.toml.
- name: Install Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@150fca883cd4034361b621bd4e6a9d34e5143606 # v1.15.4
with:
# rust/bench is its own workspace with its own lockfile and target dir.
cache-workspaces: |
.
rust/bench
# canbench is cached below on its own version instead; rust-cache's key
# includes the Cargo.lock hash and would rebuild it on every dep bump.
cache-bin: false
- name: Check bench formatting
working-directory: rust/bench
run: cargo fmt -- --check
- name: Lint bench
working-directory: rust/bench
run: cargo clippy --all-targets -- -D warnings
- name: Cache canbench
id: canbench-cache
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5.1.0
with:
path: ~/.cargo/bin/canbench
key: ${{ runner.os }}-canbench-${{ env.CANBENCH_VERSION }}
- name: Install canbench
if: steps.canbench-cache.outputs.cache-hit != 'true'
run: cargo install --version ${{ env.CANBENCH_VERSION }} --locked canbench
- name: Run perf for base branch
run: |
pushd main/rust/bench
canbench --show-summary --persist
popd
cp main/rust/bench/canbench_results.yml rust/bench/
# The report goes to the job summary rather than a PR comment: it needs no
# token, so it works the same on forks, and it stays out of the way until
# someone has a reason to look. diff.py exits non-zero when an instruction
# count regressed past the threshold — capture that, write the summary, and
# only then fail, so the numbers are always readable.
- name: Run perf for PR branch
run: |
pushd rust/bench
canbench --less-verbose --show-summary --persist > /tmp/perf.txt
diff_status=0
python diff.py canbench_results.yml ../../main/rust/bench/canbench_results.yml \
"${{ env.REGRESSION_THRESHOLD_PERCENT }}" > /tmp/table.md || diff_status=$?
{
cat /tmp/table.md
echo
echo "<details><summary>Click to see raw report</summary>"
echo
echo "\`\`\`"
cat /tmp/perf.txt
echo "\`\`\`"
echo "</details>"
} >> "$GITHUB_STEP_SUMMARY"
exit "$diff_status"
Loading
Loading