miden-debug 0.15.0

An interactive debugger for Miden VM programs
Documentation
# The substantive release checks, factored out so that pull requests, rehearsals,
# and production all run the *same* logic rather than three approximations of it.
#
# This workflow holds no credentials and can reach no production service. It is
# called by `release-ci.yml` on pull requests and by `release.yml` in production.
name: release-verify

on:
  workflow_call:
    inputs:
      ref:
        description: The commit to verify.
        required: true
        type: string
      full:
        description: Run the expensive closure verification.
        required: false
        default: false
        type: boolean

# Every job here checks out a commit and builds it; none of them write anything.
# This is also the ceiling a caller must grant on the calling job -- a called
# workflow can only downgrade the token it is handed, and asking for more than
# it was given fails the entire run before any job starts.
permissions:
  contents: read

jobs:
  lint:
    name: release lint
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - &install-release-tool
        name: Build release-tool
        run: cargo install --locked --force miden-release-tool

      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
        with:
          ref: ${{ inputs.ref }}
          # Baseline tags and merge-base checks need real history.
          fetch-depth: 0
          persist-credentials: false

      - &install-rust
        name: Install Rust
        run: |
          rustup update --no-self-update
          rustc --version

      # Package classification, publishability, private-dependency edges, the
      # frozen private-crate versions, and active `[patch]` entries. An active
      # patch is the most likely way to publish a broken crate: the workspace
      # builds, the normalized manifest looks correct, and the published crate
      # resolves to a registry version without the patched behaviour.
      - name: Lint release configuration
        run: release-tool lint

      - name: Check publication order is derivable
        run: release-tool package-order

  closure:
    name: package closure
    # Expensive: it packages every selected crate and builds a consumer that
    # resolves only through a registry. That build is the only thing proving the
    # archives are usable, because production publishes with `--no-verify`.
    if: ${{ inputs.full }}
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - *install-release-tool

      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
        with:
          ref: ${{ inputs.ref }}
          persist-credentials: false

      - *install-rust

      - name: Verify the package closure
        run: release-tool verify-closure --cache-dir "${RUNNER_TEMP}/index-cache"

  workflow-policy:
    name: workflow policy
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
        with:
          ref: ${{ inputs.ref }}
          persist-credentials: false

      # These assertions are the difference between a security model and a
      # comment describing one. Each corresponds to a way the release path could
      # silently lose a property it depends on.
      - name: Assert release workflow invariants
        run: |
          set -euo pipefail
          fail() { echo "workflow-policy: $1" >&2; exit 1; }

          # Only the production workflow may enter the production environment.
          # Match the `environment:` key rather than any mention of the name, so
          # that this check does not trip over its own search pattern.
          # Written as `if grep` rather than `grep && fail`: in an `A && B` list
          # the failure of A is invisible to `set -e`, so a broken pattern would
          # read as a passing check rather than as an error.
          for wf in .github/workflows/*.yml; do
            case "$(basename "$wf")" in
              release.yml) ;;
              *)
                if grep -Eq '^[[:space:]]+environment:[[:space:]]*release' "$wf"; then
                  fail "$wf enters the production environment"
                fi ;;
            esac
          done

          # Production must not accept scope or versions as inputs; the scope
          # comes from the reviewed .release/release.toml and nothing else.
          if [ -f .github/workflows/release.yml ]; then
            if grep -Eq '^\s+(version|unit|units|scope):' .github/workflows/release.yml; then
              fail "release.yml accepts scope or version inputs"
            fi
          fi

          # The token must never appear on a command line.
          if grep -rn -- '--token' .github/workflows/ | grep -v 'rehearsal'; then
            fail "a token is passed as a command-line argument"
          fi

          # No long-lived registry secret anywhere. Publication authenticates
          # through Trusted Publishing, which issues a short-lived token; a
          # stored one would be a second, weaker way in.
          if grep -rn 'secrets\.CARGO_REGISTRY_TOKEN' .github/workflows/; then
            fail "a long-lived crates.io secret is referenced"
          fi

          echo "workflow-policy: ok"

      - name: actionlint
        uses: docker://rhysd/actionlint@sha256:9d36088643581e728c969f35141f88139fec77280b2be23c1f66f8e40e1025e7
        with:
          args: -color