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
2 changes: 1 addition & 1 deletion .claude/skills/review-for-release/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ together — `#[cfg(unix)] #[cfg(not(unix))]` compiles to nothing, silently.
Three tests here never ran for months because of one. Grep for consecutive
cfg lines and read each pair.

**Check the counts.** Twenty macro arguments, ten crates, fourteen ci.yml jobs,
**Check the counts.** Twenty macro arguments, ten crates, fifteen ci.yml jobs,
eleven changelogs, twenty-six core examples. Every one of those numbers
appears in documentation somewhere; recount whenever a list grows.

Expand Down
155 changes: 111 additions & 44 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
name: CI

# No push trigger for `dev`: everything on dev travels through a pull
# request anyway, and a push run would twin the PR run on the same commit —
# under *required* checks, a deduplicating cancellation poisons the gate
# (a cancelled twin's "CI is green" reads as failure and blocks the merge).
# `main` keeps its push trigger because a rebase-merge mints a new SHA that
# no PR run ever checked.
on:
push:
branches: [main, dev]
branches: [main]
pull_request:
workflow_dispatch:

# One job cancels the previous run on the same branch. A pull request pushed
# three times in a minute should not occupy three runners proving the same
# thing about two obsolete commits.
# One run cancels the previous on the same ref: a pull request pushed three
# times in a minute should not occupy three runners proving the same thing
# about two obsolete commits.
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
Expand All @@ -28,9 +34,10 @@ jobs:
# A hung job should fail, not sit on a runner for six hours.
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # master
with:
toolchain: stable
components: rustfmt
- run: cargo fmt --all -- --check

Expand All @@ -39,11 +46,12 @@ jobs:
# A hung job should fail, not sit on a runner for six hours.
timeout-minutes: 30
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # master
with:
toolchain: stable
components: clippy
- uses: Swatinem/rust-cache@v2
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
# `etcd-client` compiles its gRPC stubs at build time and needs the
# `protoc` binary, which the runner image does not carry.
- run: sudo apt-get update && sudo apt-get install -y protobuf-compiler
Expand All @@ -58,9 +66,11 @@ jobs:
runs-on: ${{ matrix.os }}
timeout-minutes: 45
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # master
with:
toolchain: stable
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
# The watcher is the reason this runs on three operating systems: notify
# uses a different backend on each, and directory watching plus atomic
# saves behave differently enough to be worth proving every time.
Expand Down Expand Up @@ -114,9 +124,11 @@ jobs:
# A hung job should fail, not sit on a runner for six hours.
timeout-minutes: 60
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # master
with:
toolchain: stable
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
# Real servers, no mocks. A mock of etcd would only ever confirm what we
# already believed about etcd — and three of the facts these tests pin (a
# lazy gRPC connect, a bucket that must already exist, a first blocking
Expand Down Expand Up @@ -170,11 +182,12 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # master
with:
toolchain: stable
targets: thumbv7em-none-eabihf
- uses: Swatinem/rust-cache@v2
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
# A host build cannot check `no_std`: `std` is in the sysroot and links
# itself in. Building for a target that has no `std` at all is the only
# way to know.
Expand All @@ -194,10 +207,14 @@ jobs:
# A hung job should fail, not sit on a runner for six hours.
timeout-minutes: 30
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: taiki-e/install-action@cargo-hack
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # master
with:
toolchain: stable
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
- uses: taiki-e/install-action@7f4eb899022d8fe70b20c4f3de697aa85c309026 # v2
with:
tool: cargo-hack
# Every combination has to compile, not just the ones we happen to test.
#
# `--depth 2` rather than the full powerset: the full set is thousands
Expand All @@ -216,9 +233,11 @@ jobs:
# A hung job should fail, not sit on a runner for six hours.
timeout-minutes: 20
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # master
with:
toolchain: stable
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
# figment's behaviour is this crate's behaviour, so its contract gets its
# own job: an upgrade that changes merging or environment parsing shows up
# here rather than in a user's incident.
Expand All @@ -229,9 +248,11 @@ jobs:
# A hung job should fail, not sit on a runner for six hours.
timeout-minutes: 30
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # master
with:
toolchain: stable
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
# Not a regression gate — a shared runner is too noisy for that. It keeps
# the benchmark compiling and the README's figures reproducible by
# anyone who wants to check them.
Expand Down Expand Up @@ -284,12 +305,14 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: dtolnay/rust-toolchain@master
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # master
with:
toolchain: stable
- uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # master
with:
toolchain: ${{ matrix.rust }}
- uses: Swatinem/rust-cache@v2
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
# The lockfile has to be produced by a cargo new enough to honour
# `resolver.incompatible-rust-versions = "fallback"` from .cargo/config.toml.
# Left to the old toolchain, resolution takes the newest release of every
Expand All @@ -312,9 +335,11 @@ jobs:
env:
RUSTDOCFLAGS: -D warnings --cfg docsrs
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@nightly
- uses: Swatinem/rust-cache@v2
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # master
with:
toolchain: nightly
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
# `etcd-client` compiles its gRPC stubs at build time and needs the
# `protoc` binary, which the runner image does not carry.
- run: sudo apt-get update && sudo apt-get install -y protobuf-compiler
Expand All @@ -327,18 +352,18 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
# A README is the first thing anyone reads and the last thing anyone
# tests. A dead anchor in it is a small bug that is very easy to ship.
- uses: lycheeverse/lychee-action@v2
- uses: lycheeverse/lychee-action@e7477775783ea5526144ba13e8db5eec57747ce8 # v2
with:
args: >-
--no-progress
--include-fragments
--exclude '^https://github\.com/ctolon/'
--exclude '^https://docs\.rs/dynamic-config'
README.md ROADMAP.md CONTRIBUTING.md SECURITY.md RELEASING.md
AGENTS.md CHANGELOG.md docs/*.md
AGENTS.md CHANGELOG.md docs/*.md scripts/README.md
dynamic-config-*/README.md dynamic-config-*/CHANGELOG.md
.claude/skills/*/SKILL.md .github/ISSUE_TEMPLATE/*.md
fail: true
Expand All @@ -348,10 +373,14 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@nightly
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # master
with:
toolchain: nightly
- uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # master
with:
toolchain: stable
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
# A `serde = "1.0"` that actually needs 1.0.210 compiles against a fresh
# lockfile and breaks for the first user with an older one. This resolves
# *our* requirements to their oldest allowed version and builds against
Expand All @@ -367,16 +396,54 @@ jobs:
# oldest `trybuild` anyone could build its test suite with.
- run: cargo +stable check -p dynamic-config --locked --all-features

coverage:
name: coverage report
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # master
with:
toolchain: stable
components: llvm-tools-preview
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
- uses: taiki-e/install-action@7f4eb899022d8fe70b20c4f3de697aa85c309026 # v2
with:
tool: cargo-llvm-cov
# A report, not a gate: a threshold that fights refactoring teaches
# people to game the number. The trend lives in the job summaries; the
# lcov artifact feeds anything that wants detail.
- run: >
cargo llvm-cov --workspace --features full
--exclude dynamic-config-etcd --exclude dynamic-config-consul
--exclude dynamic-config-nats --exclude dynamic-config-vault
--exclude dynamic-config-redis --exclude dynamic-config-s3
--exclude dynamic-config-firestore --exclude dynamic-config-embedded
--lcov --output-path lcov.info
- name: summary
run: |
{
echo '## Coverage'
echo '```'
cargo llvm-cov report --summary-only
echo '```'
} >> "$GITHUB_STEP_SUMMARY"
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: coverage-lcov
path: lcov.info
retention-days: 14

actionlint:
name: workflows lint clean
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
# The workflows are code that only runs in production. actionlint
# catches the typo'd `if:` expression and the misspelled input before a
# release does.
- uses: raven-actions/actionlint@v2
- uses: raven-actions/actionlint@3d39aea434753780c3b3d4a1a31c854b4dbf49d7 # v2

# The one status branch protection requires. Requiring every job by name
# breaks the moment a matrix row is renamed; requiring this gate never
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ jobs:
id-token: write
actions: read
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
fetch-depth: 1

- uses: anthropics/claude-code-action@v1
- uses: anthropics/claude-code-action@6b082c41935b4c8a3b8b0ef85ba4ba4d9eeb8975 # v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
# No prompt: tag mode. The action reads the mention, the thread and
Expand Down
8 changes: 5 additions & 3 deletions .github/workflows/publish-dry-run.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # master
with:
toolchain: stable
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2

# Only the macro crate can be dry-run before a release: every other crate
# here depends on one below it by exact version, and a dry run resolves
Expand Down
Loading
Loading