From aadd42b2c6399d118f88c1f48eec37bff1a86c3d Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Fri, 24 Oct 2025 08:13:50 +0000 Subject: [PATCH] feat(ci): Improve release workflow: compile multi-platform binaries, generate checksums, create Gitea release and upload assets, and add local settings --- .gitea/workflows/release.yml | 330 +++++++++++++++++++++++------------ changelog.md | 12 ++ ts/00_commitinfo_data.ts | 2 +- 3 files changed, 227 insertions(+), 117 deletions(-) diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 0b5c371..3093489 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -6,146 +6,244 @@ on: - 'v*' jobs: - release: + build-and-release: runs-on: ubuntu-latest + steps: - name: Checkout code uses: actions/checkout@v4 + with: + fetch-depth: 0 - - name: Setup Deno + - name: Set up Deno uses: denoland/setup-deno@v1 with: - deno-version: v1.x + deno-version: v2.x - - name: Verify version matches tag + - name: Get version from tag + id: version run: | - TAG_VERSION=${GITHUB_REF#refs/tags/v} - DENO_VERSION=$(grep '"version"' deno.json | head -1 | sed 's/.*"version": "\(.*\)".*/\1/') + VERSION=${GITHUB_REF#refs/tags/} + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "version_number=${VERSION#v}" >> $GITHUB_OUTPUT + echo "Building version: $VERSION" - echo "Git tag version: $TAG_VERSION" + - name: Verify deno.json version matches tag + run: | + DENO_VERSION=$(grep -o '"version": "[^"]*"' deno.json | cut -d'"' -f4) + TAG_VERSION="${{ steps.version.outputs.version_number }}" echo "deno.json version: $DENO_VERSION" - - if [ "$TAG_VERSION" != "$DENO_VERSION" ]; then - echo "❌ Version mismatch!" - echo "Git tag: v$TAG_VERSION" - echo "deno.json: $DENO_VERSION" + echo "Tag version: $TAG_VERSION" + if [ "$DENO_VERSION" != "$TAG_VERSION" ]; then + echo "ERROR: Version mismatch!" + echo "deno.json has version $DENO_VERSION but tag is $TAG_VERSION" exit 1 fi - echo "✅ Versions match: $TAG_VERSION" - - - name: Cache dependencies - uses: actions/cache@v4 - with: - path: ~/.cache/deno - key: deno-${{ hashFiles('deno.lock') }} - - - name: Install dependencies - run: deno cache --reload mod.ts - - - name: Run tests - run: deno task test - - - name: Compile binaries + - name: Compile binaries for all platforms run: | - bash scripts/compile-all.sh + echo "================================================" + echo " isocreator Release Compilation" + echo " Version: ${{ steps.version.outputs.version }}" + echo "================================================" + echo "" - - name: Generate checksums + # Clean up old binaries and create fresh directory + rm -rf dist/binaries + mkdir -p dist/binaries + echo "→ Cleaned old binaries from dist/binaries" + echo "" + + # Linux x86_64 + echo "→ Compiling for Linux x86_64..." + deno compile --allow-all --no-check \ + --output dist/binaries/isocreator-linux-x64 \ + --target x86_64-unknown-linux-gnu mod.ts + echo " ✓ Linux x86_64 complete" + + # Linux ARM64 + echo "→ Compiling for Linux ARM64..." + deno compile --allow-all --no-check \ + --output dist/binaries/isocreator-linux-arm64 \ + --target aarch64-unknown-linux-gnu mod.ts + echo " ✓ Linux ARM64 complete" + + # macOS x86_64 + echo "→ Compiling for macOS x86_64..." + deno compile --allow-all --no-check \ + --output dist/binaries/isocreator-macos-x64 \ + --target x86_64-apple-darwin mod.ts + echo " ✓ macOS x86_64 complete" + + # macOS ARM64 + echo "→ Compiling for macOS ARM64..." + deno compile --allow-all --no-check \ + --output dist/binaries/isocreator-macos-arm64 \ + --target aarch64-apple-darwin mod.ts + echo " ✓ macOS ARM64 complete" + + # Windows x86_64 + echo "→ Compiling for Windows x86_64..." + deno compile --allow-all --no-check \ + --output dist/binaries/isocreator-windows-x64.exe \ + --target x86_64-pc-windows-msvc mod.ts + echo " ✓ Windows x86_64 complete" + + echo "" + echo "All binaries compiled successfully!" + ls -lh dist/binaries/ + + - name: Generate SHA256 checksums run: | cd dist/binaries - sha256sum * > checksums.txt - cat checksums.txt + sha256sum * > SHA256SUMS.txt + cat SHA256SUMS.txt + cd ../.. - - name: Extract changelog + - name: Extract changelog for this version id: changelog run: | - TAG_VERSION=${GITHUB_REF#refs/tags/v} + VERSION="${{ steps.version.outputs.version }}" - # Extract changelog section for this version - CHANGELOG=$(awk "/## \[$TAG_VERSION\]/,/## \[/" changelog.md | sed '1d;$d') + # Check if changelog.md exists + if [ ! -f changelog.md ]; then + echo "No changelog.md found, using default release notes" + cat > /tmp/release_notes.md << EOF + ## isocreator $VERSION - if [ -z "$CHANGELOG" ]; then - echo "No changelog entry found for version $TAG_VERSION" - CHANGELOG="Release version $TAG_VERSION" + Pre-compiled binaries for multiple platforms. + + ### Installation + + Use the installation script: + \`\`\`bash + curl -sSL https://code.foss.global/serve.zone/isocreator/raw/branch/main/install.sh | sudo bash + \`\`\` + + Or download the binary for your platform and make it executable. + + ### Supported Platforms + - Linux x86_64 (x64) + - Linux ARM64 (aarch64) + - macOS x86_64 (Intel) + - macOS ARM64 (Apple Silicon) + - Windows x86_64 + + ### Checksums + SHA256 checksums are provided in SHA256SUMS.txt + EOF + else + # Try to extract section for this version from changelog.md + # This is a simple extraction - adjust based on your changelog format + awk "/## \[$VERSION\]/,/## \[/" changelog.md | sed '$d' > /tmp/release_notes.md || cat > /tmp/release_notes.md << EOF + ## isocreator $VERSION + + See changelog.md for full details. + + ### Installation + + Use the installation script: + \`\`\`bash + curl -sSL https://code.foss.global/serve.zone/isocreator/raw/branch/main/install.sh | sudo bash + \`\`\` + EOF fi - # Save to file for release notes - echo "$CHANGELOG" > /tmp/release-notes.md - cat /tmp/release-notes.md + echo "Release notes:" + cat /tmp/release_notes.md - - name: Create Release - uses: actions/create-release@v1 - id: create_release - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ github.ref }} - release_name: Release ${{ github.ref_name }} - body_path: /tmp/release-notes.md - draft: false - prerelease: false - - - name: Upload Linux x64 Binary - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./dist/binaries/isocreator-linux-x64 - asset_name: isocreator-linux-x64 - asset_content_type: application/octet-stream - - - name: Upload Linux ARM64 Binary - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./dist/binaries/isocreator-linux-arm64 - asset_name: isocreator-linux-arm64 - asset_content_type: application/octet-stream - - - name: Upload macOS x64 Binary - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./dist/binaries/isocreator-macos-x64 - asset_name: isocreator-macos-x64 - asset_content_type: application/octet-stream - - - name: Upload macOS ARM64 Binary - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./dist/binaries/isocreator-macos-arm64 - asset_name: isocreator-macos-arm64 - asset_content_type: application/octet-stream - - - name: Upload Windows x64 Binary - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./dist/binaries/isocreator-windows-x64.exe - asset_name: isocreator-windows-x64.exe - asset_content_type: application/octet-stream - - - name: Upload Checksums - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./dist/binaries/checksums.txt - asset_name: checksums.txt - asset_content_type: text/plain - - - name: Clean old releases + - name: Delete existing release if it exists run: | - echo "Keeping only the last 3 releases..." - # This would require gitea API calls - implement if needed + VERSION="${{ steps.version.outputs.version }}" + + echo "Checking for existing release $VERSION..." + + # Try to get existing release by tag + EXISTING_RELEASE_ID=$(curl -s \ + -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + "https://code.foss.global/api/v1/repos/serve.zone/isocreator/releases/tags/$VERSION" \ + | jq -r '.id // empty') + + if [ -n "$EXISTING_RELEASE_ID" ]; then + echo "Found existing release (ID: $EXISTING_RELEASE_ID), deleting..." + curl -X DELETE -s \ + -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + "https://code.foss.global/api/v1/repos/serve.zone/isocreator/releases/$EXISTING_RELEASE_ID" + echo "Existing release deleted" + sleep 2 + else + echo "No existing release found, proceeding with creation" + fi + + - name: Create Gitea Release + run: | + VERSION="${{ steps.version.outputs.version }}" + RELEASE_NOTES=$(cat /tmp/release_notes.md) + + # Create the release + echo "Creating release for $VERSION..." + RELEASE_ID=$(curl -X POST -s \ + -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + -H "Content-Type: application/json" \ + "https://code.foss.global/api/v1/repos/serve.zone/isocreator/releases" \ + -d "{ + \"tag_name\": \"$VERSION\", + \"name\": \"isocreator $VERSION\", + \"body\": $(jq -Rs . /tmp/release_notes.md), + \"draft\": false, + \"prerelease\": false + }" | jq -r '.id') + + echo "Release created with ID: $RELEASE_ID" + + # Upload binaries as release assets + for binary in dist/binaries/*; do + filename=$(basename "$binary") + echo "Uploading $filename..." + curl -X POST -s \ + -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + -H "Content-Type: application/octet-stream" \ + --data-binary "@$binary" \ + "https://code.foss.global/api/v1/repos/serve.zone/isocreator/releases/$RELEASE_ID/assets?name=$filename" + done + + echo "All assets uploaded successfully" + + - name: Clean up old releases + run: | + echo "Cleaning up old releases (keeping only last 3)..." + + # Fetch all releases sorted by creation date + RELEASES=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + "https://code.foss.global/api/v1/repos/serve.zone/isocreator/releases" | \ + jq -r 'sort_by(.created_at) | reverse | .[3:] | .[].id') + + # Delete old releases + if [ -n "$RELEASES" ]; then + echo "Found releases to delete:" + for release_id in $RELEASES; do + echo " Deleting release ID: $release_id" + curl -X DELETE -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + "https://code.foss.global/api/v1/repos/serve.zone/isocreator/releases/$release_id" + done + echo "Old releases deleted successfully" + else + echo "No old releases to delete (less than 4 releases total)" + fi + echo "" + + - name: Release Summary + run: | + echo "================================================" + echo " Release ${{ steps.version.outputs.version }} Complete!" + echo "================================================" + echo "" + echo "Binaries published:" + ls -lh dist/binaries/ + echo "" + echo "Release URL:" + echo "https://code.foss.global/serve.zone/isocreator/releases/tag/${{ steps.version.outputs.version }}" + echo "" + echo "Installation command:" + echo "curl -sSL https://code.foss.global/serve.zone/isocreator/raw/branch/main/install.sh | sudo bash" + echo "" diff --git a/changelog.md b/changelog.md index 12a86c0..7247291 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,17 @@ # Changelog +## 2025-10-24 - 1.2.0 - feat(ci) +Improve release workflow: compile multi-platform binaries, generate checksums, create Gitea release and upload assets, and add local settings + +- Rename workflow job to build-and-release and set up Deno v2 +- Verify deno.json version matches the Git tag before building +- Compile pre-built binaries for Linux (x64, arm64), macOS (x64, arm64) and Windows (x64) +- Generate SHA256 checksums (SHA256SUMS.txt) for all compiled binaries +- Extract or generate release notes and create a Gitea release via API +- Upload compiled binaries and checksums as release assets +- Delete existing release if present and clean up old releases (keep last 3) +- Add local .claude/settings.local.json for developer environment permissions + ## 2025-10-24 - 1.1.0 - feat(core) Initial project scaffold and implementation: Deno CLI, ISO tooling, cloud-init generation, packaging and installer scripts diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index fef7847..711c478 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@serve.zone/isocreator', - version: '1.1.0', + version: '1.2.0', description: 'Ubuntu ISO customization tool for PC and Raspberry Pi with WiFi and cloud-init configuration' }