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
28 changes: 28 additions & 0 deletions .github/actions/cache/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: cache
description: >-
Single-source wrapper around `actions/cache`. GitHub Actions can't
parameterize a `uses:` ref, so wrapping the step in a composite is the only
way to pin the action's SHA in ONE place across every rainix workflow that
caches build outputs. Each call site passes its own `path` / `key` /
`restore-keys` (the Foundry build cache, the npm cache, etc.).
inputs:
path:
description: A list of files, directories, and patterns to cache and restore.
required: true
key:
description: An explicit key for restoring and saving the cache.
required: true
restore-keys:
description: >-
An ordered multiline string listing the prefix-matched keys used to
restore a stale cache if no cache hit occurred for `key`.
required: false
default: ''
runs:
using: composite
steps:
- uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
with:
path: ${{ inputs.path }}
key: ${{ inputs.key }}
restore-keys: ${{ inputs.restore-keys }}
22 changes: 22 additions & 0 deletions .github/actions/checkout/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: checkout
description: >-
Single-source wrapper around `actions/checkout`. GitHub Actions can't
parameterize a `uses:` ref (no `uses: ${{ env.X }}`), so the only way to pin
the checkout SHA in ONE place across every rainix workflow is to wrap it in a
composite. The `ssh-key` input covers the one call site (autopublish) that
needs a deploy-key checkout; every other site uses the default token checkout.
inputs:
ssh-key:
description: >-
Optional deploy key (e.g. `secrets.PUBLISH_PRIVATE_KEY`) for a checkout
whose pushes should trigger downstream workflows. A composite action
cannot read `secrets.*`, so the caller must plumb the secret through here.
Empty (the default) falls back to the standard GITHUB_TOKEN checkout.
required: false
default: ''
runs:
using: composite
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
with:
ssh-key: ${{ inputs.ssh-key }}
36 changes: 36 additions & 0 deletions .github/actions/gh-release/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: gh-release
description: >-
Single-source wrapper around `softprops/action-gh-release`. GitHub Actions
can't parameterize a `uses:` ref, so wrapping the step in a composite is the
only way to pin the action's SHA in ONE place across the (npm / soldeer)
GitHub Release steps in the autopublish workflow. Each call site passes its
own `tag-name` / `name` / `files`.
inputs:
tag-name:
description: The git tag to create the release against (passed to `tag_name`).
required: true
name:
description: The release title.
required: false
default: ''
files:
description: >-
Newline- or comma-separated globs of files to upload as release assets.
Empty (the default) creates a release with no attached assets.
required: false
default: ''
github-token:
description: >-
GitHub token used to create the release. A composite action cannot read
`secrets.*`, so the caller must plumb `secrets.GITHUB_TOKEN` through here.
required: true
runs:
using: composite
steps:
- uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2
with:
tag_name: ${{ inputs.tag-name }}
name: ${{ inputs.name }}
files: ${{ inputs.files }}
env:
GITHUB_TOKEN: ${{ inputs.github-token }}
84 changes: 84 additions & 0 deletions .github/actions/nix-cachix-setup/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: nix-cachix-setup
description: >-
Shared 'nix + cachix CI' preamble for the rainix reusable workflows: checkout,
nix-quick-install, the Cachix substituter/pusher, and the cache-nix-action Nix
store restore/save. This composite is the single source of truth for the
pinned third-party action SHAs used by that preamble — each SHA lives here once
instead of being copy-pasted across the reusables.
inputs:
cachix-auth-token:
description: >-
Cachix auth token. A composite action cannot read `secrets.*`, so the
caller reusable must plumb `secrets.CACHIX_AUTH_TOKEN` through to here.
Empty (the default) degrades to a read-only/anonymous Cachix pull.
required: false
default: ''
cachix-name:
description: Cachix binary cache name to substitute from / push to.
required: false
default: rainlanguage
checkout:
description: >-
Run the bundled `actions/checkout` (default). Set to 'false' if the
caller needs a non-default checkout (e.g. an ssh-key deploy-key checkout)
and runs `actions/checkout` itself before calling this composite.
required: false
default: 'true'
cache-nix:
description: >-
Run the bundled `cache-nix-action` Nix store restore/save (default). Set
to 'false' if the caller pins a different cache-nix-action version and runs
it itself.
required: false
default: 'true'
gc-max-store-size-macos:
description: >-
Optional `gc-max-store-size-macos` for the bundled cache-nix-action. Left
empty (the action's own default) unless a caller needs to cap the macOS
store before saving.
required: false
default: ''
runs:
using: composite
steps:
# Fully qualified `rainlanguage/rainix/...@main`, NOT a `./` path: inside a
# composite a `./` ref resolves against the *caller's* repository (the
# downstream consumer running this preamble), where this `checkout`
# composite does not exist. The ref must name this repo explicitly, and
# `@main` is correct for real consumers (they run against merged main).
#
# Note this makes the whole composite un-runnable on a branch that hasn't
# yet merged `.github/actions/checkout` to main: GitHub resolves and
# downloads every transitively-referenced action up front (the `if:` only
# gates execution, not the download), so this `@main` ref is fetched — and
# fails — regardless of `inputs.checkout`. That is the one-time bootstrap
# cost of single-sourcing same-repo composites at `@main`; it clears the
# moment this PR lands on main.
- uses: rainlanguage/rainix/.github/actions/checkout@main
if: ${{ inputs.checkout == 'true' }}
- uses: nixbuild/nix-quick-install-action@5bb6a3b3abe66fd09bbf250dce8ada94f856a703 # v30
with:
nix_conf: |
keep-env-derivations = true
keep-outputs = true
# Substitute prebuilt rainix derivations from the shared Cachix binary
# cache instead of rebuilding toolchain crates from source (rainix#196).
# Pushes new paths when the auth token is set; continue-on-error so a
# missing cache/token or a Cachix outage degrades to a normal build.
- uses: cachix/cachix-action@ad2ddac53f961de1989924296a1f236fcfbaa4fc # v15
continue-on-error: true
with:
name: ${{ inputs.cachix-name }}
authToken: ${{ inputs.cachix-auth-token }}
# No store-watching daemon: it checkpoints the nix DB
# concurrently with cache-nix-action and corrupts it ("database
# disk image is malformed"). Push happens once in the post step.
useDaemon: false
- name: Restore and save Nix store
if: ${{ inputs.cache-nix == 'true' }}
uses: nix-community/cache-nix-action@7df957e333c1e5da7721f60227dbba6d06080569 # v7
with:
primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}
restore-prefixes-first-match: nix-${{ runner.os }}-
gc-max-store-size-linux: 8G
gc-max-store-size-macos: ${{ inputs.gc-max-store-size-macos }}
22 changes: 22 additions & 0 deletions .github/actions/rust-cache/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: rust-cache
description: >-
Single-source wrapper around `Swatinem/rust-cache`. GitHub Actions can't
parameterize a `uses:` ref, so wrapping the step in a composite is the only
way to pin the action's SHA in ONE place across every rainix workflow that
caches Rust build artifacts. The `prefix-key` input covers the one call site
(vercel) that namespaces its cache per-workflow; every other site uses the
action's default key.
inputs:
prefix-key:
description: >-
Optional `prefix-key` for `Swatinem/rust-cache` (e.g.
`rust-${{ github.workflow }}`). Empty (the default) leaves the action's
own default prefix in place.
required: false
default: ''
runs:
using: composite
steps:
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
with:
prefix-key: ${{ inputs.prefix-key }}
48 changes: 19 additions & 29 deletions .github/workflows/check-shell.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,36 +10,26 @@ jobs:
fail-fast: false
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- uses: nixbuild/nix-quick-install-action@v30
# Shared nix + cachix CI preamble (checkout, nix-quick-install, Cachix,
# cache-nix-action). The pinned third-party action SHAs live ONCE in the
# composites; this self-test references them fully qualified at
# `rainlanguage/rainix/...@main`, exactly as downstream consumers do, so
# the self-test covers what consumers actually run and no third-party SHA
# is duplicated.
#
# BOOTSTRAP CAVEAT: the PR that first adds these composites is RED here
# until it merges. `@main` resolves against the tip of main, which does
# not yet contain `.github/actions/*`, so "Prepare all required actions"
# fails. It cannot be worked around on-branch without a regression (`./`
# would break downstream callers; a branch pin dangles post-merge; and
# GitHub downloads every transitively-referenced action up front, so even
# `checkout: 'false'` cannot dodge the preamble's internal `checkout@main`
# download). Once this PR lands on main the `@main` actions exist and this
# job is green — zero version skew, each third-party action still single-
# sourced. See the PR thread for the full analysis.
- uses: rainlanguage/rainix/.github/actions/nix-cachix-setup@main
with:
nix_conf: |
keep-env-derivations = true
keep-outputs = true
# Substitute prebuilt rainix derivations from the shared Cachix binary
# cache instead of rebuilding toolchain crates from source (rainix#196).
# Pushes new paths when CACHIX_AUTH_TOKEN is set; continue-on-error so a
# missing cache/token or a Cachix outage degrades to a normal build.
- uses: cachix/cachix-action@v15
continue-on-error: true
with:
name: rainlanguage
authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
# No store-watching daemon: it checkpoints the nix DB
# concurrently with cache-nix-action and corrupts it ("database
# disk image is malformed"). Push happens once in the post step.
useDaemon: false
- name: Restore and save Nix store
uses: nix-community/cache-nix-action@v7
with:
# restore and save a cache using this key
primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}
# if there's no cache hit, restore a cache by this prefix
restore-prefixes-first-match: nix-${{ runner.os }}-
# collect garbage until the Nix store size (in bytes) is at most this number
# before trying to save a new cache
# 1G = 1073741824
gc-max-store-size-linux: 8G
cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }}
- run: NIXPKGS_ALLOW_INSECURE=1 nix flake check --impure
- run: nix develop --command cargo release --version
- run: nix develop --command flamegraph --help
Expand Down
49 changes: 16 additions & 33 deletions .github/workflows/rainix-autopublish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,38 +49,23 @@ jobs:
id-token: write
contents: write
steps:
- uses: actions/checkout@v4
# This job needs a deploy-key (ssh-key) checkout, so it runs the shared
# `checkout` composite itself with the key, then calls the nix+cachix
# preamble with `checkout: 'false'`. The pinned checkout / cache-nix /
# nix-quick-install / Cachix SHAs all live once in the composites. Fully
# qualified ref: a bare `./` would resolve against the calling repo.
- uses: rainlanguage/rainix/.github/actions/checkout@main
with:
# PUBLISH_PRIVATE_KEY is a deploy key whose push events trigger
# downstream workflows (unlike GITHUB_TOKEN pushes which don't).
# If the consumer hasn't set it, ssh-key is empty and checkout
# falls back to GITHUB_TOKEN over HTTPS — pushes still succeed,
# they just won't trigger tag-listening workflows.
ssh-key: ${{ secrets.PUBLISH_PRIVATE_KEY }}
- uses: nixbuild/nix-quick-install-action@v30
- uses: rainlanguage/rainix/.github/actions/nix-cachix-setup@main
with:
nix_conf: |
keep-env-derivations = true
keep-outputs = true
# Substitute prebuilt rainix derivations from the shared Cachix binary
# cache instead of rebuilding toolchain crates from source (rainix#196).
# Pushes new paths when CACHIX_AUTH_TOKEN is set; continue-on-error so a
# missing cache/token or a Cachix outage degrades to a normal build.
- uses: cachix/cachix-action@v15
continue-on-error: true
with:
name: rainlanguage
authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
# No store-watching daemon: it checkpoints the nix DB
# concurrently with cache-nix-action and corrupts it ("database
# disk image is malformed"). Push happens once in the post step.
useDaemon: false
- name: Restore and save Nix store
uses: nix-community/cache-nix-action@v6
with:
primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}
restore-prefixes-first-match: nix-${{ runner.os }}-
gc-max-store-size-linux: 8G
cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }}
checkout: 'false'
# Resolve the crate list once (crates, else the back-compat singular crate).
- name: Resolve crates
run: |
Expand Down Expand Up @@ -318,7 +303,7 @@ jobs:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
- name: Publish to NPM
if: ${{ inputs.npm-package != '' && steps.npm.outputs.changed == 'true' }}
uses: JS-DevTools/npm-publish@v3
uses: JS-DevTools/npm-publish@19c28f1ef146469e409470805ea4279d47c3d35c # v3
with:
token: ${{ secrets.NPM_PUBLISH_PRIVATE_TOKEN }}
access: public
Expand All @@ -341,18 +326,16 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: GitHub Release (npm)
if: ${{ inputs.npm-package != '' && steps.npm.outputs.changed == 'true' }}
uses: softprops/action-gh-release@v2
uses: rainlanguage/rainix/.github/actions/gh-release@main
with:
tag_name: npm-${{ env.NPM_VERSION }}
tag-name: npm-${{ env.NPM_VERSION }}
name: NPM Package Release ${{ env.NPM_VERSION }}
files: npm_package_${{ env.NPM_VERSION }}.tgz
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: GitHub Release (soldeer)
if: ${{ inputs.soldeer-package != '' && steps.soldeer.outputs.changed == 'true' }}
uses: softprops/action-gh-release@v2
uses: rainlanguage/rainix/.github/actions/gh-release@main
with:
tag_name: sol-v${{ steps.soldeer.outputs.next }}
tag-name: sol-v${{ steps.soldeer.outputs.next }}
name: Soldeer Release sol-v${{ steps.soldeer.outputs.next }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
github-token: ${{ secrets.GITHUB_TOKEN }}
28 changes: 5 additions & 23 deletions .github/workflows/rainix-copy-artifacts.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,12 @@ jobs:
copy-artifacts:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: nixbuild/nix-quick-install-action@v30
# Shared nix + cachix CI preamble (checkout, nix-quick-install, Cachix,
# cache-nix-action) — pinned action SHAs live in the composite. Fully
# qualified ref: a bare `./` would resolve against the calling repo.
- uses: rainlanguage/rainix/.github/actions/nix-cachix-setup@main
with:
nix_conf: |
keep-env-derivations = true
keep-outputs = true
# Substitute prebuilt derivations from the shared Cachix cache so the
# toolchain + any prelude build don't refetch crates from crates.io (whose
# download endpoint 403s nix's User-Agent). Pushes new paths when
# CACHIX_AUTH_TOKEN is set; continue-on-error degrades gracefully.
- uses: cachix/cachix-action@v15
continue-on-error: true
with:
name: rainlanguage
authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
# No store-watching daemon: it checkpoints the nix DB concurrently
# with cache-nix-action and corrupts it. Push happens in the post step.
useDaemon: false
- name: Restore and save Nix store
uses: nix-community/cache-nix-action@v7
with:
primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}
restore-prefixes-first-match: nix-${{ runner.os }}-
gc-max-store-size-linux: 8G
cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }}
# No Foundry build cache here on purpose: this is a clean-build determinism
# check, so out/ must be regenerated fresh — and caching only cache/ (not
# out/) gives no real speedup, since forge recompiles to rebuild the
Expand Down
Loading
Loading