diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index f8307c5098..22715fc9c9 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -11,29 +11,18 @@ jobs: PUBLIC_WALLETCONNECT_PROJECT_ID: ${{ secrets.WALLETCONNECT_PROJECT_ID || 'test' }} COMMIT_SHA: ${{ github.sha }} steps: - - uses: actions/checkout@v4 - - uses: nixbuild/nix-quick-install-action@v30 + # Shared nix + cachix preamble (checkout, nix-quick-install, Cachix, + # cache-nix-action). The third-party action SHAs are pinned once in the + # rainix composite. + - uses: rainlanguage/rainix/.github/actions/nix-cachix-setup@main with: - nix_conf: | - keep-env-derivations = true - keep-outputs = true - - uses: cachix/cachix-action@v15 - continue-on-error: true - with: - name: rainlanguage - authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} - 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 }}- + cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} gc-max-store-size-linux: 1G - - uses: Swatinem/rust-cache@v2 + - uses: rainlanguage/rainix/.github/actions/rust-cache@main with: prefix-key: rust-${{ github.workflow }} - name: Cache npm - uses: actions/cache@v4 + uses: rainlanguage/rainix/.github/actions/cache@main with: path: ~/.npm key: npm-${{ runner.os }}-${{ github.workflow }}-${{ hashFiles('**/package-lock.json') }} diff --git a/.github/workflows/deploy-subgraph.yaml b/.github/workflows/deploy-subgraph.yaml index c65e9b97a8..645697e8c5 100644 --- a/.github/workflows/deploy-subgraph.yaml +++ b/.github/workflows/deploy-subgraph.yaml @@ -11,25 +11,17 @@ jobs: GOLDSKY_TOKEN: ${{ secrets.CI_GOLDSKY_TOKEN }} GOLDSKY_SUBGRAPH_NAME: raindex steps: - - uses: actions/checkout@v4 + - uses: rainlanguage/rainix/.github/actions/checkout@main - name: Free disk space - uses: jlumbroso/free-disk-space@v1.3.1 - - uses: nixbuild/nix-quick-install-action@v30 + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + # Shared nix + cachix preamble (nix-quick-install, Cachix, + # cache-nix-action). The third-party action SHAs are pinned once in the + # rainix composite. checkout: false because free-disk-space runs between + # the checkout above and nix-quick-install. + - uses: rainlanguage/rainix/.github/actions/nix-cachix-setup@main with: - nix_conf: | - keep-env-derivations = true - keep-outputs = true - - uses: cachix/cachix-action@v15 - continue-on-error: true - with: - name: rainlanguage - authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} - 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 }}- + checkout: false + cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} gc-max-store-size-linux: 1G # subgraph-deploy builds from the committed subgraph/abis + subgraph/generated, # so it needs no forge build and runs on the slim subgraph shell. diff --git a/.github/workflows/manual-rs-release.yml b/.github/workflows/manual-rs-release.yml index 8e40e121ec..3fe3435cd6 100644 --- a/.github/workflows/manual-rs-release.yml +++ b/.github/workflows/manual-rs-release.yml @@ -7,28 +7,12 @@ jobs: id-token: write contents: read steps: - - uses: actions/checkout@v4 - - uses: nixbuild/nix-quick-install-action@v30 + # Shared nix + cachix preamble (checkout, nix-quick-install, Cachix, + # cache-nix-action). The third-party action SHAs are pinned once in the + # rainix composite. + - uses: rainlanguage/rainix/.github/actions/nix-cachix-setup@main with: - nix_conf: | - keep-env-derivations = true - keep-outputs = true - - uses: cachix/cachix-action@v15 - continue-on-error: true - with: - name: rainlanguage - authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} - useDaemon: false - - name: Restore and save Nix store - uses: nix-community/cache-nix-action@v6 - 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 + cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} gc-max-store-size-linux: 1G - run: nix develop .#rust-shell --command cargo release --workspace # forwards status to telegram chat if this ci fails or gets canceled, only runs for default branch diff --git a/.github/workflows/npm-package-release.yml b/.github/workflows/npm-package-release.yml index c178eb7e8f..27641a15f7 100644 --- a/.github/workflows/npm-package-release.yml +++ b/.github/workflows/npm-package-release.yml @@ -28,47 +28,34 @@ jobs: version: ${{ env.NEW_VERSION }} steps: # checkout with SSH key to allow pushing version bump commits back to repo - - uses: actions/checkout@v4 + - uses: rainlanguage/rainix/.github/actions/checkout@main with: ssh-key: ${{ secrets.PUBLISH_PRIVATE_KEY }} # WASM builds require significant disk space; free up space to prevent build failures - name: Free disk space - uses: jlumbroso/free-disk-space@v1.3.1 + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 with: swap-storage: false - # install nix for building WASM artifacts and running tests - - uses: nixbuild/nix-quick-install-action@v30 + # Shared nix + cachix preamble (nix-quick-install, Cachix, + # cache-nix-action). The third-party action SHAs are pinned once in the + # rainix composite. checkout: false because the ssh-key checkout above and + # free-disk-space both run before nix-quick-install. + - uses: rainlanguage/rainix/.github/actions/nix-cachix-setup@main with: - nix_conf: | - keep-env-derivations = true - keep-outputs = true - # pull rainix derivations from shared Cachix; push new ones if the - # token is set. continue-on-error so a token miss / Cachix outage - # degrades gracefully. - - uses: cachix/cachix-action@v15 - continue-on-error: true - with: - name: rainlanguage - authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} - 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 - - uses: Swatinem/rust-cache@v2 + checkout: false + cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} + - uses: rainlanguage/rainix/.github/actions/rust-cache@main with: prefix-key: rust-${{ github.workflow }} - name: Cache npm - uses: actions/cache@v4 + uses: rainlanguage/rainix/.github/actions/cache@main with: path: ~/.npm key: npm-${{ runner.os }}-${{ github.workflow }}-${{ hashFiles('**/package-lock.json') }} restore-keys: npm-${{ runner.os }}- # setup node with npm registry for OIDC-based publishing (no NPM_TOKEN needed) - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: "24.x" registry-url: "https://registry.npmjs.org" @@ -262,19 +249,18 @@ jobs: git push -u origin "npm-raindex-v${{ env.RAINDEX_NEW_VERSION }}-uc-v${{ env.UC_NEW_VERSION }}" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # Create gitHub release with tarballs + # Create gitHub release with tarballs. The softprops/action-gh-release SHA + # is pinned once in the rainix composite. - name: Create GitHub Release if: ${{ env.OLD_HASH != env.NEW_HASH }} - id: gh_release - uses: softprops/action-gh-release@v2 + uses: rainlanguage/rainix/.github/actions/gh-release@main with: - tag_name: npm-raindex-v${{ env.RAINDEX_NEW_VERSION }}-uc-v${{ env.UC_NEW_VERSION }} + tag-name: npm-raindex-v${{ env.RAINDEX_NEW_VERSION }}-uc-v${{ env.UC_NEW_VERSION }} name: NPM Package Release raindex v${{ env.RAINDEX_NEW_VERSION }} ui-components v${{ env.UC_NEW_VERSION }} files: | raindex_npm_package_${{ env.RAINDEX_NEW_VERSION }}.tgz ui_components_npm_package_${{ env.UC_NEW_VERSION }}.tgz - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + github-token: ${{ secrets.GITHUB_TOKEN }} # forwards status to telegram chat if this ci fails or gets canceled, only runs for default branch - name: Forward CI Status if: always() diff --git a/.github/workflows/test-js-bindings.yaml b/.github/workflows/test-js-bindings.yaml index 21e254cefc..da7bc18638 100644 --- a/.github/workflows/test-js-bindings.yaml +++ b/.github/workflows/test-js-bindings.yaml @@ -6,31 +6,22 @@ jobs: env: COMMIT_SHA: ${{ github.sha }} steps: - - uses: actions/checkout@v4 + - uses: rainlanguage/rainix/.github/actions/checkout@main - name: Free disk space - uses: jlumbroso/free-disk-space@v1.3.1 - - uses: nixbuild/nix-quick-install-action@v30 + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + # Shared nix + cachix preamble (nix-quick-install, Cachix, + # cache-nix-action). The third-party action SHAs are pinned once in the + # rainix composite. checkout: false because free-disk-space runs between + # the checkout above and nix-quick-install. + - uses: rainlanguage/rainix/.github/actions/nix-cachix-setup@main with: - nix_conf: | - keep-env-derivations = true - keep-outputs = true - - uses: cachix/cachix-action@v15 - continue-on-error: true - with: - name: rainlanguage - authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} - 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 - - uses: Swatinem/rust-cache@v2 + checkout: false + cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} + - uses: rainlanguage/rainix/.github/actions/rust-cache@main with: prefix-key: rust-${{ github.workflow }} - name: Cache npm - uses: actions/cache@v4 + uses: rainlanguage/rainix/.github/actions/cache@main with: path: ~/.npm key: npm-${{ runner.os }}-${{ github.workflow }}-${{ hashFiles('**/package-lock.json') }} diff --git a/.github/workflows/test-ui-components.yaml b/.github/workflows/test-ui-components.yaml index 10127203ea..d6b4db6dcc 100644 --- a/.github/workflows/test-ui-components.yaml +++ b/.github/workflows/test-ui-components.yaml @@ -16,30 +16,17 @@ jobs: env: COMMIT_SHA: ${{ github.sha }} steps: - - uses: actions/checkout@v2 + - uses: rainlanguage/rainix/.github/actions/checkout@main - name: Free disk space - uses: jlumbroso/free-disk-space@v1.3.1 - - uses: nixbuild/nix-quick-install-action@v30 + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + # Shared nix + cachix preamble (nix-quick-install, Cachix, + # cache-nix-action). The third-party action SHAs are pinned once in the + # rainix composite. checkout: false because free-disk-space runs between + # the checkout above and nix-quick-install. + - uses: rainlanguage/rainix/.github/actions/nix-cachix-setup@main with: - nix_conf: | - keep-env-derivations = true - keep-outputs = true - - uses: cachix/cachix-action@v15 - continue-on-error: true - with: - name: rainlanguage - authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} - useDaemon: false - - name: Restore and save Nix store - uses: nix-community/cache-nix-action@v6 - 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 + checkout: false + cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} gc-max-store-size-linux: 10G - run: | nix develop .#wasm-shell -c bash -c ' diff --git a/.github/workflows/test-webapp.yaml b/.github/workflows/test-webapp.yaml index 5e6e088fdf..d2946ea3bf 100644 --- a/.github/workflows/test-webapp.yaml +++ b/.github/workflows/test-webapp.yaml @@ -16,30 +16,17 @@ jobs: env: COMMIT_SHA: ${{ github.sha }} steps: - - uses: actions/checkout@v2 + - uses: rainlanguage/rainix/.github/actions/checkout@main - name: Free disk space - uses: jlumbroso/free-disk-space@v1.3.1 - - uses: nixbuild/nix-quick-install-action@v30 + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + # Shared nix + cachix preamble (nix-quick-install, Cachix, + # cache-nix-action). The third-party action SHAs are pinned once in the + # rainix composite. checkout: false because free-disk-space runs between + # the checkout above and nix-quick-install. + - uses: rainlanguage/rainix/.github/actions/nix-cachix-setup@main with: - nix_conf: | - keep-env-derivations = true - keep-outputs = true - - uses: cachix/cachix-action@v15 - continue-on-error: true - with: - name: rainlanguage - authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} - useDaemon: false - - name: Restore and save Nix store - uses: nix-community/cache-nix-action@v6 - 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 + checkout: false + cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} gc-max-store-size-linux: 10G - run: | nix develop .#wasm-shell -c bash -c ' diff --git a/.github/workflows/vercel-docs-preview.yaml b/.github/workflows/vercel-docs-preview.yaml index aded1ddbc3..455b6cfd03 100644 --- a/.github/workflows/vercel-docs-preview.yaml +++ b/.github/workflows/vercel-docs-preview.yaml @@ -18,35 +18,24 @@ jobs: env: COMMIT_SHA: ${{ github.sha }} steps: - - uses: actions/checkout@v4 + - uses: rainlanguage/rainix/.github/actions/checkout@main - name: Free disk space - uses: jlumbroso/free-disk-space@v1.3.1 - - uses: nixbuild/nix-quick-install-action@v30 + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + # Shared nix + cachix preamble (nix-quick-install, Cachix, + # cache-nix-action). The third-party action SHAs are pinned once in the + # rainix composite. checkout: false because free-disk-space runs between + # the checkout above and nix-quick-install. + - uses: rainlanguage/rainix/.github/actions/nix-cachix-setup@main with: - nix_conf: | - keep-env-derivations = true - keep-outputs = true - - uses: cachix/cachix-action@v15 - continue-on-error: true - with: - name: rainlanguage - authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} - 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 - - uses: Swatinem/rust-cache@v2 + checkout: false + cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} + - uses: rainlanguage/rainix/.github/actions/rust-cache@main with: # Restore this branch's own cache if it has one, else fall back to the - # cache the prod run saves on main (shared prefix-key). save-if keeps - # this branch's cache warm across re-runs. + # cache the prod run saves on main (shared prefix-key). prefix-key: rust-vercel-docs - save-if: true - name: Cache npm - uses: actions/cache@v4 + uses: rainlanguage/rainix/.github/actions/cache@main with: path: ~/.npm key: npm-${{ runner.os }}-${{ github.workflow }}-${{ hashFiles('**/package-lock.json') }} diff --git a/.github/workflows/vercel-docs-prod.yaml b/.github/workflows/vercel-docs-prod.yaml index 27f7ea6b03..ab030e8c29 100644 --- a/.github/workflows/vercel-docs-prod.yaml +++ b/.github/workflows/vercel-docs-prod.yaml @@ -15,33 +15,24 @@ jobs: env: COMMIT_SHA: ${{ github.sha }} steps: - - uses: actions/checkout@v4 + - uses: rainlanguage/rainix/.github/actions/checkout@main - name: Free disk space - uses: jlumbroso/free-disk-space@v1.3.1 - - uses: nixbuild/nix-quick-install-action@v30 + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + # Shared nix + cachix preamble (nix-quick-install, Cachix, + # cache-nix-action). The third-party action SHAs are pinned once in the + # rainix composite. checkout: false because free-disk-space runs between + # the checkout above and nix-quick-install. + - uses: rainlanguage/rainix/.github/actions/nix-cachix-setup@main with: - nix_conf: | - keep-env-derivations = true - keep-outputs = true - - uses: cachix/cachix-action@v15 - continue-on-error: true - with: - name: rainlanguage - authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} - 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 - - uses: Swatinem/rust-cache@v2 + checkout: false + cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} + - uses: rainlanguage/rainix/.github/actions/rust-cache@main with: # Shared across the docs preview/prod workflows so a preview run (off # main) restores the cache the prod run saves on main. prefix-key: rust-vercel-docs - name: Cache npm - uses: actions/cache@v4 + uses: rainlanguage/rainix/.github/actions/cache@main with: path: ~/.npm key: npm-${{ runner.os }}-${{ github.workflow }}-${{ hashFiles('**/package-lock.json') }} diff --git a/.github/workflows/vercel-preview.yaml b/.github/workflows/vercel-preview.yaml index 3c9a85966b..e3bc536402 100644 --- a/.github/workflows/vercel-preview.yaml +++ b/.github/workflows/vercel-preview.yaml @@ -59,20 +59,20 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@v4 - - uses: nixbuild/nix-quick-install-action@v30 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - uses: nixbuild/nix-quick-install-action@5bb6a3b3abe66fd09bbf250dce8ada94f856a703 # v30 with: nix_conf: | keep-env-derivations = true keep-outputs = true - - uses: cachix/cachix-action@v15 + - uses: cachix/cachix-action@ad2ddac53f961de1989924296a1f236fcfbaa4fc # v15 continue-on-error: true with: name: rainlanguage authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} useDaemon: false - name: Restore and save Nix store - uses: nix-community/cache-nix-action@v7 + 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 }}- diff --git a/.github/workflows/vercel-prod.yaml b/.github/workflows/vercel-prod.yaml index 9ca6f68b42..9e3b608984 100644 --- a/.github/workflows/vercel-prod.yaml +++ b/.github/workflows/vercel-prod.yaml @@ -56,20 +56,20 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@v4 - - uses: nixbuild/nix-quick-install-action@v30 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - uses: nixbuild/nix-quick-install-action@5bb6a3b3abe66fd09bbf250dce8ada94f856a703 # v30 with: nix_conf: | keep-env-derivations = true keep-outputs = true - - uses: cachix/cachix-action@v15 + - uses: cachix/cachix-action@ad2ddac53f961de1989924296a1f236fcfbaa4fc # v15 continue-on-error: true with: name: rainlanguage authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} useDaemon: false - name: Restore and save Nix store - uses: nix-community/cache-nix-action@v7 + 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 }}- diff --git a/.github/workflows/wasm-artifacts.yaml b/.github/workflows/wasm-artifacts.yaml index b2a934fa01..4dfdd5ca5a 100644 --- a/.github/workflows/wasm-artifacts.yaml +++ b/.github/workflows/wasm-artifacts.yaml @@ -6,27 +6,18 @@ jobs: env: COMMIT_SHA: ${{ github.sha }} steps: - - uses: actions/checkout@v4 + - uses: rainlanguage/rainix/.github/actions/checkout@main - name: Free disk space - uses: jlumbroso/free-disk-space@v1.3.1 - - uses: nixbuild/nix-quick-install-action@v30 + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + # Shared nix + cachix preamble (nix-quick-install, Cachix, + # cache-nix-action). The third-party action SHAs are pinned once in the + # rainix composite. checkout: false because free-disk-space runs between + # the checkout above and nix-quick-install. + - uses: rainlanguage/rainix/.github/actions/nix-cachix-setup@main with: - nix_conf: | - keep-env-derivations = true - keep-outputs = true - - uses: cachix/cachix-action@v15 - continue-on-error: true - with: - name: rainlanguage - authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} - 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 - - uses: Swatinem/rust-cache@v2 + checkout: false + cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} + - uses: rainlanguage/rainix/.github/actions/rust-cache@main with: prefix-key: rust-${{ github.workflow }} - run: nix develop .#wasm-shell -c cargo build --profile release-wasm --target wasm32-unknown-unknown --lib -p raindex_js_api diff --git a/.github/workflows/wasm-browser-test.yaml b/.github/workflows/wasm-browser-test.yaml index 7f392245f2..6f39ac0333 100644 --- a/.github/workflows/wasm-browser-test.yaml +++ b/.github/workflows/wasm-browser-test.yaml @@ -6,30 +6,21 @@ jobs: env: COMMIT_SHA: ${{ github.sha }} steps: - - uses: actions/checkout@v4 + - uses: rainlanguage/rainix/.github/actions/checkout@main - name: Free disk space - uses: jlumbroso/free-disk-space@v1.3.1 + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 with: # Keep chromium — wasm-pack test --headless --chrome needs it. large-packages: false - - uses: nixbuild/nix-quick-install-action@v30 + # Shared nix + cachix preamble (nix-quick-install, Cachix, + # cache-nix-action). The third-party action SHAs are pinned once in the + # rainix composite. checkout: false because free-disk-space runs between + # the checkout above and nix-quick-install. + - uses: rainlanguage/rainix/.github/actions/nix-cachix-setup@main with: - nix_conf: | - keep-env-derivations = true - keep-outputs = true - - uses: cachix/cachix-action@v15 - continue-on-error: true - with: - name: rainlanguage - authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} - 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 - - uses: Swatinem/rust-cache@v2 + checkout: false + cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} + - uses: rainlanguage/rainix/.github/actions/rust-cache@main with: prefix-key: rust-${{ github.workflow }} - run: | diff --git a/.github/workflows/wasm-test.yaml b/.github/workflows/wasm-test.yaml index 1fd8526a31..f6934ecb0f 100644 --- a/.github/workflows/wasm-test.yaml +++ b/.github/workflows/wasm-test.yaml @@ -6,27 +6,18 @@ jobs: env: COMMIT_SHA: ${{ github.sha }} steps: - - uses: actions/checkout@v4 + - uses: rainlanguage/rainix/.github/actions/checkout@main - name: Free disk space - uses: jlumbroso/free-disk-space@v1.3.1 - - uses: nixbuild/nix-quick-install-action@v30 + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + # Shared nix + cachix preamble (nix-quick-install, Cachix, + # cache-nix-action). The third-party action SHAs are pinned once in the + # rainix composite. checkout: false because free-disk-space runs between + # the checkout above and nix-quick-install. + - uses: rainlanguage/rainix/.github/actions/nix-cachix-setup@main with: - nix_conf: | - keep-env-derivations = true - keep-outputs = true - - uses: cachix/cachix-action@v15 - continue-on-error: true - with: - name: rainlanguage - authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} - 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 - - uses: Swatinem/rust-cache@v2 + checkout: false + cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} + - uses: rainlanguage/rainix/.github/actions/rust-cache@main with: prefix-key: rust-${{ github.workflow }} - run: nix develop .#wasm-shell -c bash -c "CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUNNER=wasm-bindgen-test-runner cargo test --target wasm32-unknown-unknown --lib -p raindex_quote -p raindex_bindings -p raindex_js_api -p raindex_common" diff --git a/script/check-pinned-actions.sh b/script/check-pinned-actions.sh new file mode 100755 index 0000000000..5da2727e36 --- /dev/null +++ b/script/check-pinned-actions.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LicenseRef-DCL-1.0 +# SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd +# +# Prints "OK" iff every third-party GitHub Action referenced by a `uses:` line +# in `.github/workflows/` is pinned to a full 40-hex commit SHA rather than a +# mutable ref (a branch like `@main` or a tag like `@v4`). Mutable refs are the +# supply-chain hole this guards: whoever controls the upstream tag controls the +# code our CI runs, so a compromised `@v4` runs in our pipeline the moment it +# moves. +# +# First-party `rainlanguage/*` refs are excluded: the org's shared CI (rainix / +# github-chore reusable workflows + composite actions) is intentionally tracked +# at `@main`, so pinning those is an org-wide decision rather than this repo's. +# The shared third-party actions used by the nix/cachix CI preamble are wrapped +# in rainix composite actions that pin each SHA once, so a workflow satisfies +# this check either by SHA-pinning a third-party action inline or by delegating +# to a `rainlanguage/rainix/.github/actions/*` composite that already pins it. +# +# Consumed by `test/PinnedActions.t.sol` via FFI. Output is one of: +# OK - every third-party action is SHA-pinned +# UNPINNED: ... - one or more refs use a mutable tag/branch +# +# Always exits 0 so the test sees the message rather than an ffi failure. + +set -euo pipefail + +workflows_dir=".github/workflows" + +# Extract every `uses:` ref. Tolerates leading `- ` and arbitrary indentation, +# quoted or unquoted values, and trailing `# comment`. +refs=$( + grep -rhoE '^[[:space:]]*-?[[:space:]]*uses:[[:space:]]*[^[:space:]#]+' "$workflows_dir" \ + | sed -E 's/.*uses:[[:space:]]*//; s/["'\'']//g' +) + +unpinned="" +while IFS= read -r ref; do + [ -z "$ref" ] && continue + + # Skip first-party shared CI (intentionally tracked at @main). + case "$ref" in + rainlanguage/*) continue ;; + esac + + # Local actions (`./...`) and docker refs are not tag-pinnable here. + case "$ref" in + ./*) continue ;; + docker://*) continue ;; + esac + + # Split owner/repo[/path]@ref on the LAST '@'. + pin="${ref##*@}" + + # A pinned ref is exactly 40 lowercase hex chars (a full commit SHA). + if ! printf '%s' "$pin" | grep -qE '^[0-9a-f]{40}$'; then + unpinned="$unpinned $ref" + fi +done <<<"$refs" + +if [ -n "$unpinned" ]; then + printf 'UNPINNED:%s' "$unpinned" + exit 0 +fi + +printf 'OK' diff --git a/test/PinnedActions.t.sol b/test/PinnedActions.t.sol new file mode 100644 index 0000000000..2f2abe51ec --- /dev/null +++ b/test/PinnedActions.t.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: LicenseRef-DCL-1.0 +// SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd +pragma solidity =0.8.25; + +import {Test} from "forge-std-1.16.1/src/Test.sol"; + +/// @title PinnedActionsTest +/// @notice Every third-party GitHub Action referenced by a `uses:` line in +/// `.github/workflows/` must be pinned to a full 40-hex commit SHA, never a +/// mutable tag (a "v4" tag) or branch (a "main" branch). A mutable ref lets +/// whoever controls the upstream tag inject code into our CI the moment it +/// moves (https://github.com/rainlanguage/raindex/issues/620). First-party +/// `rainlanguage/*` shared-CI refs are intentionally excluded -- pinning those +/// is an org-wide decision, not this repo's. A workflow therefore satisfies the +/// invariant either by SHA-pinning a third-party action inline or by delegating +/// to a `rainlanguage/rainix/.github/actions/*` composite that pins it once. +/// +/// `script/check-pinned-actions.sh` enumerates the refs (via FFI) and returns +/// `OK` only when every third-party action is SHA-pinned; otherwise it returns +/// `UNPINNED: ...` listing the offenders. Reintroducing a floating ref +/// (e.g. an unpinned "actions/checkout" at a tag) therefore reds this test +/// with the exact ref. +contract PinnedActionsTest is Test { + function testEveryThirdPartyActionIsShaPinned() external { + string[] memory cmd = new string[](2); + cmd[0] = "bash"; + cmd[1] = "script/check-pinned-actions.sh"; + bytes memory out = vm.ffi(cmd); + + // On failure the actual value is `UNPINNED: ...`, naming each + // mutable third-party action ref so the regression is obvious. + assertEq(string(out), "OK", "a third-party github action is not pinned to a commit sha"); + } +}