Skip to content

Release

Release #14

Workflow file for this run

name: Release
on:
release:
types: [published]
env:
RUSTFLAGS: -Dwarnings
CARGO_TERM_COLOR: always
BINARY_NAME: "pwdgen"
CRATES_TOKEN: ${{ secrets.CRATES_TOKEN }}
VT_API_KEY: ${{ secrets.VT_API_KEY }}
jobs:
check-version:
runs-on: ubuntu-latest
outputs:
result: ${{ steps.version_check.outputs.version_match }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Check version
id: version_check
shell: pwsh
run: |
$TAG_VERSION = $env:GITHUB_REF -replace '^refs/tags/v', ''
$CARGO_VERSION = (Select-String -Path Cargo.toml -Pattern '^version = "(.+)"').Matches.Groups[1].Value
Write-Output "Tag version: $TAG_VERSION"
Write-Output "Cargo.toml version: $CARGO_VERSION"
if ($TAG_VERSION -eq $CARGO_VERSION) {
Write-Output "version_match=true" >> $env:GITHUB_OUTPUT
Write-Output "Versions match. Proceeding with the release check."
} else {
Write-Output "version_match=false" >> $env:GITHUB_OUTPUT
Write-Output "Version mismatch detected!"
}
- name: Display version_match output
run: echo "${{ steps.version_check.outputs.version_match }}"
check-last-commit:
runs-on: ubuntu-latest
outputs:
result: ${{ steps.check_last_commit.outputs.passed_test }}
checks: ${{ steps.check_last_commit.outputs.checks }}
markdown_checks: ${{ steps.check_last_commit.outputs.markdown_checks }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Check last commit status
id: check_last_commit
shell: pwsh
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
$LAST_COMMIT_SHA = git rev-parse HEAD
$CHECK_RUNS = gh api repos/$env:GITHUB_REPOSITORY/commits/$LAST_COMMIT_SHA/check-runs --jq '.check_runs[] | {name, conclusion}'
$FAILED_CHECKS = $CHECK_RUNS | ConvertFrom-Json | Where-Object { $_.conclusion -ne 'success' }
$ALL_CHECKS = $CHECK_RUNS | ConvertFrom-Json | ForEach-Object { "$($_.name): $($_.conclusion)" } -join ', '
$MARKDOWN_CHECKS = $CHECK_RUNS | ConvertFrom-Json | ForEach-Object { "- **$($_.name)**: $($_.conclusion)" } -join "`n"
Write-Output "checks=$ALL_CHECKS" >> $env:GITHUB_OUTPUT
Write-Output "markdown_checks=$MARKDOWN_CHECKS" >> $env:GITHUB_OUTPUT
if ($FAILED_CHECKS) {
Write-Output "passed_test=false" >> $env:GITHUB_OUTPUT
$FAILED_NAMES = ($FAILED_CHECKS | ForEach-Object { $_.name }) -join ', '
Write-Output "The last commit does not have all successful tests. Failed checks: $FAILED_NAMES"
exit 1
} else {
Write-Output "passed_test=true" >> $env:GITHUB_OUTPUT
Write-Output "All checks passed for the last commit."
}
- name: Display passed_test output
run: echo "${{ steps.check_last_commit.outputs.passed_test }}"
- name: Display checks output
run: echo "${{ steps.check_last_commit.outputs.markdown_checks }}"
handle-release:
needs: [check-version, check-last-commit]
if: always()
outputs:
status: ${{ steps.handle.outputs.status }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Handle failed checks
id: handle
shell: pwsh
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
$TAG_VERSION = $env:GITHUB_REF -replace '^refs/tags/v', ''
$CHECK_RUNS =
$ISSUE_BODY = ""
if ('${{ needs.check-version.outputs.result }}' -eq 'false') {
$ISSUE_BODY += "## Version\n"
$ISSUE_BODY += "Version mismatch detected between tag and Cargo.toml."
$ISSUE_BODY += " The release has been unpublished.\n"
}
if ('${{ needs.check-last-commit.outputs.result }}' -eq 'false') {
$ISSUE_BODY += "## Tests\n"
$ISSUE_BODY += "The last commit does not have all successful tests.\n"
$ISSUE_BODY += "${{ needs.check-last-commit.outputs.markdown_checks }}"
}
$ISSUE_URL = gh issue create --label bug --title "Release $TAG_VERSION Check Failed" --body $ISSUE_BODY --assignee "@me"
if ($env:GITHUB_EVENT_NAME -eq "release") {
Write-Output "status=false" >> $env:GITHUB_OUTPUT
gh release delete $TAG_VERSION --yes
Write-Output "Release has been unpublished due to check failure."
git push origin :refs/tags/v$TAG_VERSION
Write-Output "Tag v$TAG_VERSION has been deleted."
}
Write-Output "status=true" >> $env:GITHUB_OUTPUT
Write-Output "An issue has been created: $ISSUE_URL"
- name: Display status output
run: echo "${{ steps.handle.outputs.status }}"
release:
needs: handle-release
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
rust_version: [stable]
include:
- os: macos-latest
os_name: "macos"
asset_extension: ""
asset_content_type: application/octet-stream
- os: windows-latest
os_name: "windows"
asset_extension: ".exe"
asset_content_type: application/octet-stream
- os: ubuntu-latest
os_name: "ubuntu"
asset_extension: ""
asset_content_type: application/octet-stream
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust_version }}
override: true
- name: Prepare Ubuntu environment
if: ${{ matrix.os == 'ubuntu-latest' }}
run: |
sudo apt update
sudo apt install -y libxcb-shape0-dev libxcb-xfixes0-dev
- name: Build release
run: cargo build --release
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: "${{ env.BINARY_NAME }}-${{ github.event.release.tag_name }}-${{ env.BINARY_NAME }}-${{ matrix.os_name }}${{ matrix.asset_extension }}"
path: target/release/${{ env.BINARY_NAME }}${{ matrix.asset_extension }}
- name: Upload Release Asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: ./target/release/${{ env.BINARY_NAME }}${{ matrix.asset_extension }}
asset_name: "${{ env.BINARY_NAME }}-${{ matrix.os_name }}${{ matrix.asset_extension }}"
asset_content_type: ${{ matrix.asset_content_type }}
- name: VirusTotal Scan
uses: crazy-max/ghaction-virustotal@v4
with:
vt_api_key: ${{ env.VT_API_KEY }}
update_release_body: true
files: ./target/release/${{ env.BINARY_NAME }}${{ matrix.asset_extension }}
- name: Notify success
if: success()
run: echo "Release process completed successfully!"
- name: Notify failure
if: failure()
run: echo "Release process failed, check logs for details."
publish-crate:
needs: handle-release
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Build
run: cargo build --release
- name: Publish to Crates.io
run: cargo publish --token ${CRATES_TOKEN}