diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..9e3b88a --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,114 @@ +name: Release + +on: + push: + tags: + - "v*" + +permissions: + contents: write + +jobs: + test: + name: Test before release + runs-on: ubuntu-latest + steps: + - name: Step Security + uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1 + with: + disable-sudo-and-containers: true + egress-policy: block + allowed-endpoints: > + api.github.com:443 + objects.githubusercontent.com:443 + release-assets.githubusercontent.com:443 + github.com:443 + index.crates.io:443 + static.crates.io:443 + static.rust-lang.org:443 + proxy.golang.org:443 + + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Install Go + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 + with: + go-version: stable + + - name: Install Rust + uses: dtolnay/rust-toolchain@efa25f7f19611383d5b0ccf2d1c8914531636bf9 + with: + toolchain: stable + + - name: cargo build + run: cargo build --locked --verbose + env: + CARGO_TERM_COLOR: always + + - name: cargo test + run: cargo test --locked --verbose + env: + CARGO_TERM_COLOR: always + + - name: go test + run: | + go generate ./... + go test ./... + + - name: run snapshot tests + run: cargo test --locked --verbose --test cli + + publish: + name: Publish to crates.io + needs: test + runs-on: ubuntu-latest + steps: + - name: Step Security + uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1 + with: + disable-sudo-and-containers: true + egress-policy: block + allowed-endpoints: > + crates.io:443 + index.crates.io:443 + static.crates.io:443 + static.rust-lang.org:443 + github.com:443 + + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Install Rust + uses: dtolnay/rust-toolchain@efa25f7f19611383d5b0ccf2d1c8914531636bf9 + with: + toolchain: stable + + - name: Publish + run: cargo publish -p arcjet-gravity --locked + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + CARGO_TERM_COLOR: always + + github-release: + name: Create GitHub Release + needs: publish + runs-on: ubuntu-latest + steps: + - name: Step Security + uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1 + with: + disable-sudo-and-containers: true + egress-policy: block + allowed-endpoints: > + api.github.com:443 + github.com:443 + uploads.github.com:443 + + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Create GitHub Release + env: + GH_TOKEN: ${{ github.token }} + run: gh release create "${{ github.ref_name }}" --generate-notes diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 0000000..99f91f2 --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,44 @@ +# Release + +Publishing to crates.io is automated via GitHub Actions but requires a manual +tag push to initiate. + +## Prerequisites + +A `CARGO_REGISTRY_TOKEN` secret must be configured in the repository's GitHub +settings (Settings → Secrets and variables → Actions). This token must have +publish permissions for the `arcjet-gravity` crate on crates.io. + +## Process + +It looks like this: + +1. Update the version in `cmd/gravity/Cargo.toml` and land the change on `main`. +2. Tag the release commit and push the tag: + ```sh + git tag v0.1.0 + git push origin v0.1.0 + ``` +3. The [Release workflow](.github/workflows/release.yml) runs automatically: + 1. **Test** — runs the full test suite (cargo test, go test, snapshot tests). + 2. **Publish** — publishes `arcjet-gravity` to crates.io. + 3. **GitHub Release** — creates a GitHub Release with auto-generated notes. +4. Verify the release on [crates.io](https://crates.io/crates/arcjet-gravity) + and on the repository's + [Releases page](https://github.com/arcjet/gravity/releases). + +## Versioning + +This project follows [Semantic Versioning](https://semver.org/). While the +project is in early development (`0.x`), minor version bumps may include +breaking changes. + +## Troubleshooting + +- **Publish fails with permission error**: check that the `CARGO_REGISTRY_TOKEN` + secret is set and the token has not expired. +- **Publish fails with version conflict**: the version in `Cargo.toml` must be + greater than the latest published version on crates.io. You cannot re-publish + a version that has already been published. +- **Tests fail**: the release is aborted. Fix the issue on `main`, delete the + tag (`git push origin :refs/tags/v0.1.0`), and start again. diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..d638770 --- /dev/null +++ b/renovate.json @@ -0,0 +1,49 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [":dependencyDashboardApproval"], + "enabledManagers": ["cargo", "github-actions"], + "minimumReleaseAge": "7 days", + "schedule": [], + "updateNotScheduled": false, + "semanticCommitScope": "", + "semanticCommitType": "deps", + "packageRules": [ + { + "matchManagers": ["github-actions"], + "dependencyDashboardCategory": "GitHub Actions updates" + }, + { + "matchManagers": ["cargo"], + "dependencyDashboardCategory": "Rust updates" + }, + { + "matchDepTypes": ["devDependencies"], + "semanticCommitScope": "dev", + "semanticCommitType": "deps", + "automerge": true + }, + { + "matchUpdateTypes": ["patch"], + "automerge": true + }, + { + "matchUpdateTypes": ["lockFileMaintenance"], + "automerge": true + } + ], + "lockFileMaintenance": { + "enabled": true + }, + "prBodyTemplate": "{{{header}}}{{{table}}}{{{warnings}}}{{{notes}}}{{{changelogs}}}", + "prBodyColumns": ["Package", "Change"], + "ignorePresets": ["mergeConfidence:all-badges"], + "vulnerabilityAlerts": { + "groupName": null, + "dependencyDashboardApproval": true, + "rangeStrategy": "update-lockfile", + "commitMessageSuffix": "[security]", + "branchTopic": "{{{datasource}}}-{{{depNameSanitized}}}-vulnerability", + "prCreation": "immediate", + "vulnerabilityFixStrategy": "lowest" + } +}