Skip to content

release: Bump version to 0.4.2 #26

release: Bump version to 0.4.2

release: Bump version to 0.4.2 #26

Workflow file for this run

name: Release
on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
version:
description: "Release version (e.g., v0.1.0)"
required: true
type: string
permissions:
contents: write
packages: write
jobs:
build:
name: Build Binaries
strategy:
matrix:
include:
- os: linux
arch: amd64
goos: linux
goarch: amd64
runner: ubuntu-latest
- os: linux
arch: arm64
goos: linux
goarch: arm64
runner: ubuntu-latest
- os: darwin
arch: amd64
goos: darwin
goarch: amd64
runner: macos-latest
- os: darwin
arch: arm64
goos: darwin
goarch: arm64
runner: macos-latest
runs-on: ${{ matrix.runner }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.23"
- name: Get version
id: version
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
VERSION="${{ github.event.inputs.version }}"
else
VERSION="${{ github.ref_name }}"
fi
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "version_clean=${VERSION#v}" >> $GITHUB_OUTPUT
- name: Get build metadata
id: metadata
run: |
echo "commit=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
echo "date=$(date -u +'%Y-%m-%d')" >> $GITHUB_OUTPUT
echo "author=Leonardo Zanobi" >> $GITHUB_OUTPUT
echo "website=https://commandchronicles.dev" >> $GITHUB_OUTPUT
- name: Import Apple Developer Certificate
if: matrix.os == 'darwin'
uses: apple-actions/import-codesign-certs@v1
with:
p12-file-base64: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_P12_BASE64 }}
p12-password: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_PASSWORD }}
keychain: signing_temp
create-keychain: true
- name: Build binary
run: |
BINARY_NAME="ccr-${{ matrix.os }}-${{ matrix.arch }}"
echo "Building ${{ matrix.os }}/${{ matrix.arch }} binary with pure Go..."
# Pure Go build - no CGO needed since we use modernc.org/sqlite
CGO_ENABLED=0 GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} go build -ldflags="-X main.version=${{ steps.version.outputs.version_clean }} -X main.commit=${{ steps.metadata.outputs.commit }} -X main.date=${{ steps.metadata.outputs.date }} -X 'main.author=${{ steps.metadata.outputs.author }}' -X main.website=${{ steps.metadata.outputs.website }} -w -s" -o "${BINARY_NAME}" .
# Verify binary was created
ls -la "${BINARY_NAME}"
file "${BINARY_NAME}" || echo "file command not available"
# Show binary info
echo "Binary size: $(du -h ${BINARY_NAME} | cut -f1)"
- name: Sign and Notarize macOS Binary
if: matrix.os == 'darwin'
run: |
BINARY_NAME="ccr-${{ matrix.os }}-${{ matrix.arch }}"
# Check if signing identity is set
if [ -z "${{ secrets.APPLE_SIGNING_IDENTITY }}" ]; then
echo "❌ Error: APPLE_SIGNING_IDENTITY secret is not set!"
echo "Available signing identities on this system:"
security find-identity -v -p codesigning || echo "Could not list identities"
echo ""
echo "Please add APPLE_SIGNING_IDENTITY secret to your repository with a value like:"
echo "Developer ID Application: Your Name (TEAMID)"
exit 1
fi
# Sign the binary
echo "Signing macOS binary with Developer ID..."
echo "Using signing identity: ${{ secrets.APPLE_SIGNING_IDENTITY }}"
codesign --force --options runtime --sign "${{ secrets.APPLE_SIGNING_IDENTITY }}" "${BINARY_NAME}"
# Verify signature
echo "Verifying signature..."
codesign -vvv --deep --strict "${BINARY_NAME}"
# Prepare for notarization
echo "Preparing for notarization..."
ditto -c -k --keepParent "${BINARY_NAME}" "${BINARY_NAME}.zip"
# Notarize with Apple
echo "Submitting for notarization (this may take a few minutes)..."
NOTARIZATION_SUCCESS=false
SUBMISSION_OUTPUT=$(xcrun notarytool submit "${BINARY_NAME}.zip" \
--apple-id "${{ secrets.APPLE_ID }}" \
--password "${{ secrets.APPLE_APP_PASSWORD }}" \
--team-id "${{ secrets.APPLE_TEAM_ID }}" \
--wait 2>&1) || NOTARIZE_STATUS=$?
echo "$SUBMISSION_OUTPUT"
# Check if notarization was rejected
if echo "$SUBMISSION_OUTPUT" | grep -q "status: Rejected"; then
echo "⚠️ Notarization was rejected. Fetching log for details..."
SUBMISSION_ID=$(echo "$SUBMISSION_OUTPUT" | grep "id:" | head -1 | awk '{print $2}')
echo "Fetching notarization log for submission ID: $SUBMISSION_ID"
xcrun notarytool log "$SUBMISSION_ID" \
--apple-id "${{ secrets.APPLE_ID }}" \
--password "${{ secrets.APPLE_APP_PASSWORD }}" \
--team-id "${{ secrets.APPLE_TEAM_ID }}" \
notarization-log.json || true
echo "Notarization log:"
cat notarization-log.json | jq '.' 2>/dev/null || cat notarization-log.json || echo "Could not retrieve log"
echo ""
echo "Common rejection reasons:"
echo "- Binary not signed with hardened runtime (--options runtime)"
echo "- Missing entitlements"
echo "- Invalid code signature"
echo "- Binary compiled with incompatible SDK version"
echo ""
echo "⚠️ WARNING: Continuing with signed but not notarized binary"
echo "Users will see a Gatekeeper warning but can still run the app by right-clicking and selecting Open"
elif echo "$SUBMISSION_OUTPUT" | grep -q "status: Accepted"; then
NOTARIZATION_SUCCESS=true
echo "✅ Notarization accepted!"
fi
# Only staple if notarization was successful
if [ "$NOTARIZATION_SUCCESS" = true ]; then
# Staple the notarization ticket
echo "Stapling notarization ticket..."
if xcrun stapler staple "${BINARY_NAME}"; then
echo "✅ Successfully stapled notarization ticket"
# Verify stapling
echo "Verifying stapled notarization..."
xcrun stapler validate "${BINARY_NAME}" || echo "⚠️ Staple validation failed but continuing"
echo "✅ macOS code signing and notarization completed successfully!"
else
echo "⚠️ Failed to staple notarization ticket but continuing with signed binary"
fi
else
echo "⚠️ Skipping stapling due to notarization failure"
echo "✅ macOS code signing completed (without notarization)"
fi
- name: Generate checksum
run: |
BINARY_NAME="ccr-${{ matrix.os }}-${{ matrix.arch }}"
if [[ "${{ matrix.os }}" == "darwin" ]]; then
shasum -a 256 "${BINARY_NAME}" > "${BINARY_NAME}.sha256"
else
sha256sum "${BINARY_NAME}" > "${BINARY_NAME}.sha256"
fi
echo "Generated checksum for ${BINARY_NAME}:"
cat "${BINARY_NAME}.sha256"
- name: Upload binary artifact
uses: actions/upload-artifact@v4
with:
name: ccr-${{ matrix.os }}-${{ matrix.arch }}
path: |
ccr-${{ matrix.os }}-${{ matrix.arch }}
ccr-${{ matrix.os }}-${{ matrix.arch }}.sha256
retention-days: 5
release:
name: Create Release
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get version
id: version
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
VERSION="${{ github.event.inputs.version }}"
else
VERSION="${{ github.ref_name }}"
fi
echo "version=${VERSION}" >> $GITHUB_OUTPUT
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: ./artifacts
- name: Prepare release assets
run: |
mkdir -p ./release-assets
find ./artifacts -name "ccr-*" -type f -exec cp {} ./release-assets/ \;
# Create combined checksums file
cd ./release-assets
find . -name "*.sha256" -exec cat {} \; > checksums.txt
echo "Release assets:"
ls -la
echo "Checksums file:"
cat checksums.txt
- name: Generate release notes
id: release_notes
run: |
# Get the git tag message
TAG_MESSAGE=$(git tag -l --format='%(contents)' ${{ steps.version.outputs.version }})
# Create release notes with tag message and standard sections
cat << EOF > release_notes.md
## ccr ${{ steps.version.outputs.version }}
${TAG_MESSAGE}
### 📦 Binaries
| Platform | Architecture | Download |
|----------|-------------|----------|
| Linux | x86_64 | [ccr-linux-amd64](https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/ccr-linux-amd64) |
| Linux | ARM64 | [ccr-linux-arm64](https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/ccr-linux-arm64) |
| macOS | Intel | [ccr-darwin-amd64](https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/ccr-darwin-amd64) |
| macOS | Apple Silicon | [ccr-darwin-arm64](https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/ccr-darwin-arm64) |
### 📋 Checksums
Download [checksums.txt](https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/checksums.txt) to verify binary integrity.
### 📚 Documentation
See the [README](https://github.com/${{ github.repository }}/blob/main/README.md) for installation and usage instructions.
---
**Full Changelog**: https://github.com/${{ github.repository }}/commits/${{ steps.version.outputs.version }}
EOF
echo "Generated release notes:"
cat release_notes.md
- name: Create GitHub Release
run: |
# Check if release already exists and delete it
if gh release view "${{ steps.version.outputs.version }}" > /dev/null 2>&1; then
echo "Release ${{ steps.version.outputs.version }} already exists, deleting it"
gh release delete "${{ steps.version.outputs.version }}" --yes || true
fi
# Determine if this is a prerelease
PRERELEASE_FLAG=""
if [[ "${{ steps.version.outputs.version }}" =~ -(rc|beta|alpha|dev) ]]; then
PRERELEASE_FLAG="--prerelease"
fi
# Create the release
echo "Creating release with assets from ./release-assets/"
assets=""
for file in ./release-assets/*; do
if [ -f "$file" ]; then
assets="$assets $file"
fi
done
echo "Assets to upload: $assets"
gh release create "${{ steps.version.outputs.version }}" \
--title "🚀 CommandChronicles CLI ${{ steps.version.outputs.version }} - Secure Shell History Management" \
--notes-file release_notes.md \
$PRERELEASE_FLAG \
$assets
echo "✅ Release created successfully"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Cleanup artifacts
if: always()
run: |
echo "Cleaning up artifacts..."
# No need to delete artifacts as they'll expire automatically
notify:
name: Post-Release Notifications
needs: [build, release]
runs-on: ubuntu-latest
if: success()
steps:
- name: Release Success
run: |
echo "🎉 Release ${{ github.ref_name }} completed successfully!"
echo "📦 Binaries built for 4 platforms (Linux and macOS)"
echo "✅ GitHub release created with enhanced formatting"
echo "🔗 Release URL: https://github.com/${{ github.repository }}/releases/tag/${{ github.ref_name }}"
echo "📊 Release features: Direct download links, security verification, quick start guide"
echo "🚀 Installation command: curl -fsSL https://raw.githubusercontent.com/${{ github.repository }}/main/scripts/install.sh | sh"