name: Release
on:
push:
tags:
- 'v*.*.*' workflow_dispatch: inputs:
version:
description: 'The version tag to use for the release (e.g., v1.0.0)'
required: true
type: string
permissions:
contents: write
env:
CARGO_TERM_COLOR: always
CRATE_NAME: mail_laser
jobs:
build_assets:
name: Build Asset (${{ matrix.platform.target }})
strategy:
fail-fast: false matrix:
platform:
- release_for: Linux-x86_64
os: ubuntu-latest
target: x86_64-unknown-linux-gnu
bin: mail_laser asset_suffix: linux-x86_64
- release_for: macOS-x86_64
os: macos-latest
target: x86_64-apple-darwin
bin: mail_laser asset_suffix: macos-x86_64
- release_for: macOS-aarch64
os: macos-latest target: aarch64-apple-darwin
bin: mail_laser asset_suffix: macos-aarch64
- release_for: Windows-x86_64
os: windows-latest
target: x86_64-pc-windows-msvc
bin: mail_laser.exe asset_suffix: windows-x86_64.exe
runs-on: ${{ matrix.platform.os }}
steps:
- name: Check out repo
uses: actions/checkout@v4
- name: Cache cargo & target directories
uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.platform.target }}
- name: Build binary using actions-rust-cross
uses: houseabsolute/actions-rust-cross@v1
with:
target: ${{ matrix.platform.target }}
args: "--release --verbose --bin ${{ env.CRATE_NAME }}" strip: true
- name: Install UPX (Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get update -y
sudo apt-get install -y upx-ucl
- name: Install UPX (macOS)
if: runner.os == 'macOS'
run: brew install upx
- name: Install UPX (Windows)
if: runner.os == 'Windows'
run: choco install upx --no-progress --yes
- name: Prepare Artifact and Compress with UPX
id: artifact_details
shell: bash run: |
BINARY_NAME="${{ matrix.platform.bin }}"
ASSET_NAME="${{ env.CRATE_NAME }}-${{ matrix.platform.asset_suffix }}"
# Adjust path based on OS for target directory
if [[ "${{ runner.os }}" == "Windows" ]]; then
TARGET_DIR="target/${{ matrix.platform.target }}/release"
BINARY_PATH="$TARGET_DIR/$BINARY_NAME"
else
TARGET_DIR="target/${{ matrix.platform.target }}/release"
BINARY_PATH="$TARGET_DIR/$BINARY_NAME"
fi
echo "Target directory: $TARGET_DIR"
echo "Calculated binary path: $BINARY_PATH"
echo "Calculated asset name: $ASSET_NAME"
if [[ ! -f "$BINARY_PATH" ]]; then
echo "Error: Binary not found at $BINARY_PATH"
echo "Listing contents of $TARGET_DIR:"
ls -l "$TARGET_DIR" || echo "Could not list $TARGET_DIR"
exit 1
fi
# Compress the binary with UPX (skip on macOS)
if [[ "${{ runner.os }}" != "macOS" ]]; then
echo "Compressing binary with UPX..."
upx --best --lzma "$BINARY_PATH"
else
echo "Skipping UPX compression on macOS."
fi
# Rename binary to the desired asset name AFTER potential compression
# Ensure the target directory exists before moving (should exist, but belt-and-suspenders)
mkdir -p "$TARGET_DIR"
mv "$BINARY_PATH" "$TARGET_DIR/$ASSET_NAME"
echo "Renamed binary to $TARGET_DIR/$ASSET_NAME"
echo "asset_path=$TARGET_DIR/$ASSET_NAME" >> $GITHUB_OUTPUT
echo "asset_name=$ASSET_NAME" >> $GITHUB_OUTPUT
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: ${{ steps.artifact_details.outputs.asset_name }}
path: ${{ steps.artifact_details.outputs.asset_path }}
if-no-files-found: error
release:
name: Create GitHub Release
needs: build_assets
runs-on: ubuntu-latest
steps:
- name: Check out repo for changelog generation
uses: actions/checkout@v4
with:
fetch-tags: true
fetch-depth: 0 repository: ${{ github.repository }}
token: ${{ secrets.GITHUB_TOKEN }}
- name: Generate and Commit Changelog
run: |
set -e # Exit immediately if a command exits with a non-zero status.
echo "Setting up git-chglog..."
# Create a temporary directory for extraction
mkdir chglog_tmp
# Download git-chglog archive
wget https://github.com/git-chglog/git-chglog/releases/download/v0.15.4/git-chglog_0.15.4_linux_amd64.tar.gz -O chglog.tar.gz
# Extract into the temporary directory
tar -xvzf chglog.tar.gz -C chglog_tmp
echo "Generating full changelog for repository..."
# Generate the full changelog history for the repo file
# Assuming default behavior generates full history. Adjust if your config needs specific args.
./chglog_tmp/git-chglog -o CHANGELOG.md
# NEXT_TAG is still needed for the commit message and branch name below
NEXT_TAG="${{ github.event_name == 'workflow_dispatch' && github.event.inputs.version || github.ref_name }}"
echo "Cleaning up git-chglog files..."
# Clean up downloaded archive and temporary directory
rm chglog.tar.gz
rm -rf chglog_tmp
echo "Configuring git user..."
# Configure git user
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
# Check if CHANGELOG.md has changes
if git diff --quiet CHANGELOG.md; then
echo "No changes detected in CHANGELOG.md. Skipping commit."
else
echo "Changes detected in CHANGELOG.md. Committing..."
# Fetch the latest main branch from origin
# Use refs/heads/main to be explicit about fetching the branch, not a tag named main
git fetch origin refs/heads/main
# Create a new branch based on the fetched origin/main
# Use a unique branch name to avoid conflicts if workflow reruns
BRANCH_NAME="changelog-update-${NEXT_TAG//\//-}"
git checkout -b "$BRANCH_NAME" origin/main
# Add, commit the changelog to the new branch
git add CHANGELOG.md
# Use --allow-empty in case the changelog hasn't changed (e.g., rerunning on same tag) - though checked above
git commit -m "chore(docs): update CHANGELOG for release $NEXT_TAG [skip ci]"
echo "Pushing changelog update to main branch..."
# Push the new local branch specifically to the remote *branch* main
# Use --force-with-lease or handle potential conflicts if necessary, though unlikely for a bot commit
git push origin "$BRANCH_NAME":refs/heads/main
# Clean up the temporary local branch (optional but good practice)
# Checkout detached HEAD first to allow deletion of the current branch
git checkout --detach
git branch -D "$BRANCH_NAME" || echo "Could not delete local branch $BRANCH_NAME"
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Download all build artifacts
uses: actions/download-artifact@v4
with:
path: artifacts/build
- name: List downloaded artifacts for debugging
run: |
echo "Listing downloaded build artifacts:"
find artifacts/build -type f
# Can optionally list the generated CHANGELOG.md here if needed for debugging
# ls -l CHANGELOG.md
echo "---"
- name: Create Release and Upload Assets
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.version || github.ref_name }}
name: Release ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.version || github.ref_name }}
body_path: CHANGELOG.md
draft: false
prerelease: false files: artifacts/build/*/*