diff --git a/.github/workflows/release-crates.yml b/.github/workflows/release-crates.yml index 20d9e0a..a8e58e7 100644 --- a/.github/workflows/release-crates.yml +++ b/.github/workflows/release-crates.yml @@ -1,24 +1,77 @@ name: Release Crates on: workflow_call: + inputs: + package: + description: 'Specific package to publish (for workspaces). When empty, publishes the root crate.' + required: false + default: '' + type: string + dry-run: + description: 'Run cargo publish with --dry-run instead of actually publishing' + required: false + default: false + type: boolean + requires-private-deps: + description: 'Requires private dependencies to be fetched, sets up ssh-agent' + required: false + default: false + type: boolean + require-lockfile: + description: 'Require a Cargo.lock file to be present; passes --locked to cargo' + required: false + default: false + type: boolean + secrets: + CARGO_REGISTRY_TOKEN: + description: 'The crates.io API token used to publish' + required: false + SSH_PRIVATE_KEY: + description: 'SSH private key for fetching private dependencies' + required: false + SSH_PRIVATE_KEY_2: + description: 'SSH private key for fetching private dependencies' + required: false + SSH_PRIVATE_KEY_3: + description: 'SSH private key for fetching private dependencies' + required: false -permissions: - contents: write +permissions: {} jobs: - release_crates: - runs-on: ubuntu-24.04-arm - steps: - - uses: actions/checkout@v6 - - name: Install Rust toolchain - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 - - name: Cargo Build Release - run: cargo build --release - - name: Cargo Package - run: cargo package --allow-dirty - - name: Publish to Crates.io - run: cargo publish - env: - CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} - \ No newline at end of file + release_crates: + runs-on: + group: init4-runners + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + persist-credentials: false + - name: Setup ssh-agent + if: ${{ inputs.requires-private-deps == true }} + uses: webfactory/ssh-agent@v0.9.1 + with: + ssh-private-key: | + ${{ secrets.SSH_PRIVATE_KEY }} + ${{ secrets.SSH_PRIVATE_KEY_2 }} + ${{ secrets.SSH_PRIVATE_KEY_3 }} + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + - name: Publish to crates.io + env: + CARGO_NET_GIT_FETCH_WITH_CLI: true + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + PACKAGE: ${{ inputs.package }} + LOCKED: ${{ inputs.require-lockfile }} + DRY_RUN: ${{ inputs.dry-run }} + run: | + if [ "$DRY_RUN" != "true" ] && [ -z "$CARGO_REGISTRY_TOKEN" ]; then + echo "::error::CARGO_REGISTRY_TOKEN is required when dry-run is false" + exit 1 + fi + args=() + [ -n "$PACKAGE" ] && args+=(--package "$PACKAGE") + [ "$LOCKED" = "true" ] && args+=(--locked) + [ "$DRY_RUN" = "true" ] && args+=(--dry-run) + cargo publish "${args[@]}" diff --git a/docs/release-crates.md b/docs/release-crates.md index 083ab31..716264b 100644 --- a/docs/release-crates.md +++ b/docs/release-crates.md @@ -5,6 +5,64 @@ ```yml release-crates: uses: init4tech/actions/.github/workflows/release-crates.yml@main + secrets: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} ``` ## Optional Parameters + +### `package` + +**Description:** Specific package to publish (for workspaces). When empty, publishes the root crate. + +**Type**: `string` + +**Default Value:** `''` + +### `dry-run` + +**Description:** Runs `cargo publish --dry-run` instead of actually publishing to crates.io + +**Type**: `boolean` + +**Default Value:** `false` + +**Allowed values:** `false`, `true` + +### `requires-private-deps` + +**Description:** Will require the use of private dependencies in the repository, meaning an ssh key needs to be added to ssh-agent + +**Type**: `boolean` + +**Default Value:** `false` + +**Allowed values:** `false`, `true` + +### `require-lockfile` + +**Description:** Will require a `Cargo.lock` file to be present and pass `--locked` to cargo. Note: many publishable libraries `.gitignore` `Cargo.lock`; only enable this if the lockfile is committed. + +**Type**: `boolean` + +**Default Value:** `false` + +**Allowed values:** `false`, `true` + +## Optional Secrets + +### `CARGO_REGISTRY_TOKEN` + +**Description:** The crates.io API token used to publish the crate. Required unless `dry-run` is set to `true`. + +### `SSH_PRIVATE_KEY` + +**Description:** The SSH private key to be used for private dependencies, required if `requires-private-deps` is set to `true` + +### `SSH_PRIVATE_KEY_2` + +**Description:** Additional SSH private key for private dependencies + +### `SSH_PRIVATE_KEY_3` + +**Description:** Additional SSH private key for private dependencies diff --git a/examples/example-release-crates.yml b/examples/example-release-crates.yml index d409b76..8cb64fe 100644 --- a/examples/example-release-crates.yml +++ b/examples/example-release-crates.yml @@ -1,18 +1,29 @@ -name: add binaries to release +name: Release crate to crates.io on: push: tags: - - 'v*' + - 'v*' # this will trigger anytime a tag is pushed matching the regex v* (v1.0.0, v2.0.0, etc.) permissions: contents: write -# this job will compile your rust project and publish the to crates.io -# the job will run the following steps: -# - cargo build --release -# - cargo package -# - cargo publish +# this job will publish your rust crate to crates.io via `cargo publish`. jobs: - upload-binaries: + release-crates: uses: init4tech/actions/.github/workflows/release-crates.yml@main + with: + # Uncomment to publish a specific workspace package + # package: my-crate + # Uncomment to require a committed Cargo.lock + # require-lockfile: true + # Uncomment when the crate depends on private git repositories + # requires-private-deps: true + # Uncomment to exercise the workflow without publishing + # dry-run: true + secrets: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + # Only needed when requires-private-deps is true + # SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + # SSH_PRIVATE_KEY_2: ${{ secrets.SSH_PRIVATE_KEY_2 }} + # SSH_PRIVATE_KEY_3: ${{ secrets.SSH_PRIVATE_KEY_3 }}