name: Date-based Release
on:
schedule:
- cron: '0 10 1 * *'
workflow_dispatch:
inputs:
force:
description: 'Force create release even if one exists for today'
required: false
default: false
type: boolean
skip_publish:
description: 'Skip publishing to crates.io'
required: false
default: false
type: boolean
push:
branches: [ main ]
paths-ignore:
- 'README.md'
- 'docs/**'
- '.github/**'
- '*.md'
env:
CARGO_TERM_COLOR: always
jobs:
check-and-release:
name: Create Date-based Release
runs-on: ubuntu-latest
outputs:
should_release: ${{ steps.check.outputs.should_release }}
tag_name: ${{ steps.version.outputs.TAG_NAME }}
version: ${{ steps.version.outputs.VERSION }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Configure Git
run: .github/scripts/configure_git.sh
- name: Generate version and tag
id: version
run: .github/scripts/generate_version.sh
- name: Check if should create release
id: check
run: .github/scripts/check_release.sh "${{ steps.version.outputs.TAG_NAME }}" "${{ github.event.inputs.force }}" "${{ github.event_name }}"
- name: Install Rust stable
if: steps.check.outputs.should_release == 'true'
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo registry
if: steps.check.outputs.should_release == 'true'
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-release-cargo-${{ hashFiles('Cargo.lock') }}
- name: Update Cargo.toml version
if: steps.check.outputs.should_release == 'true'
run: .github/scripts/update_cargo_version.sh "${{ steps.version.outputs.VERSION }}"
- name: Update Cargo.lock
if: steps.check.outputs.should_release == 'true'
run: .github/scripts/update_cargo_lock.sh
- name: Build and test
if: steps.check.outputs.should_release == 'true'
run: .github/scripts/build_and_test.sh
- name: Commit version changes and create tag
if: steps.check.outputs.should_release == 'true'
run: .github/scripts/commit_and_tag.sh "${{ steps.version.outputs.TAG_NAME }}" "${{ steps.version.outputs.VERSION }}" "${{ github.event_name }}"
- name: Generate changelog
if: steps.check.outputs.should_release == 'true'
id: changelog
run: .github/scripts/generate_changelog.sh "${{ steps.version.outputs.VERSION }}" "${{ steps.version.outputs.TAG_NAME }}" "${{ github.event_name }}" "${{ github.repository }}"
- name: Create GitHub Release
if: steps.check.outputs.should_release == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: .github/scripts/create_github_release.sh "${{ steps.version.outputs.TAG_NAME }}" "${{ steps.version.outputs.VERSION }}" "${{ github.event_name }}" "${{ steps.changelog.outputs.CHANGELOG }}" "${{ vars.USE_AUTO_GENERATED_NOTES || 'false' }}"
quality-checks:
name: Pre-publish Quality Checks
runs-on: ubuntu-latest
needs: check-and-release
if: needs.check-and-release.outputs.should_release == 'true' && github.event.inputs.skip_publish != 'true'
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ needs.check-and-release.outputs.tag_name }}
- name: Get MSRV from Cargo.toml
id: msrv
run: |
MSRV=$(grep '^rust-version' Cargo.toml | sed 's/.*"\(.*\)".*/\1/')
echo "MSRV is $MSRV"
echo "version=$MSRV" >> $GITHUB_OUTPUT
- name: Install Rust MSRV
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ steps.msrv.outputs.version }}
components: rustfmt
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-quality-checks-cargo-${{ hashFiles('Cargo.lock') }}
- name: Verify Rust version
run: |
echo "Expected MSRV: ${{ steps.msrv.outputs.version }}"
rustc --version
rustc --version | grep -q "${{ steps.msrv.outputs.version }}" || (echo "Rust version mismatch"; exit 1)
- name: Build and test (including doctests)
run: .github/scripts/build_and_test.sh
- name: Check formatting
run: .github/scripts/pre_publish_checks.sh
publish-crate:
name: Publish to crates.io
runs-on: ubuntu-latest
needs: [check-and-release, quality-checks]
if: needs.check-and-release.outputs.should_release == 'true' && github.event.inputs.skip_publish != 'true'
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ needs.check-and-release.outputs.tag_name }}
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-publish-cargo-${{ hashFiles('Cargo.lock') }}
- name: Publish to crates.io
run: cargo publish
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
generate-sbom:
name: Generate and Attach SBOM
runs-on: ubuntu-latest
needs: check-and-release
if: needs.check-and-release.outputs.should_release == 'true'
continue-on-error: true
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ needs.check-and-release.outputs.tag_name }}
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo registry and target
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-sbom-cargo-${{ hashFiles('Cargo.lock') }}
restore-keys: |
${{ runner.os }}-sbom-cargo-
- name: Cache cargo-cyclonedx installation
id: cache-cyclonedx
uses: actions/cache@v4
with:
path: ~/.cargo/bin/cargo-cyclonedx
key: ${{ runner.os }}-cargo-cyclonedx-0.5.7
- name: Install cargo-cyclonedx
if: steps.cache-cyclonedx.outputs.cache-hit != 'true'
run: cargo install cargo-cyclonedx --version 0.5.7 --locked
- name: Verify project builds
run: cargo check --locked
- name: Generate SBOM files
run: .github/scripts/generate_sbom.sh
- name: Upload SBOM files to release
if: success()
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.check-and-release.outputs.tag_name }}
files: |
rsdo-sbom.json
rsdo-sbom.xml
fail_on_unmatched_files: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}