Compare commits

...
10 Commits
Author SHA1 Message Date
Tobias Gesellchen b80f8e958b debug: add tag validation debugging to identify release workflow issue 2026-01-10 01:32:12 +01:00
Tobias Gesellchen 7117ff6592 Fix GitHub Actions permissions for release workflow
- Add contents:write permission to allow updating releases
- Add actions:read permission for artifact downloads
- Resolves 'Resource not accessible by integration' error
2026-01-10 01:19:40 +01:00
Tobias Gesellchen d7b1c94b9a Fix directory flattening in release workflow
- Use dedicated collection directory to avoid naming conflicts
- Simplify file movement logic by using release-files directory
- Update artifact upload paths to match new structure
- Resolves mv errors when files have same names as directories
2026-01-10 01:15:45 +01:00
Tobias Gesellchen 3cc45ebd20 debug: add comprehensive directory listings to diagnose build conflicts
Add ls -la output for:
- Working directory before/after build
- Go build cache location and contents
- Go module cache contents
- Post-build state verification

Simple directory listings often reveal file permission issues,
cached artifacts, or leftover files that cause 'File exists' errors
better than complex debugging output.
2026-01-10 01:08:13 +01:00
Tobias Gesellchen a30251854c fix: add debugging and improve build robustness for file conflicts
- Clean build environment before building (remove existing files, clean cache)
- Add atomic checksum generation using temp directory
- Improve error handling with explicit build failure detection
- Add debugging output to diagnose 'File exists' errors
- Use basename in temp operations to avoid path issues

This should resolve the 'Cannot open: File exists' errors occurring
during the darwin/arm64 build process.
2026-01-10 01:07:41 +01:00
Tobias Gesellchen 1a1d37b885 fix: resolve directory overwrite error in checksums generation
Use find -mindepth 2 to only move files from subdirectories, avoiding
the 'mv: cannot overwrite directory' error when flattening the artifact
directory structure. This ensures only the actual binary and checksum
files are moved, not the directories themselves.

Fixes the sha256sum failure in the Generate Checksums workflow step.
2026-01-10 01:04:49 +01:00
Tobias Gesellchen 666839dd4f feat: provide both combined and individual checksum files in releases
- Generate individual SHA256/SHA512 checksums for each binary in matrix jobs
- Maintain combined checksums.sha256/checksums.sha512 files for all binaries
- Upload both types to release assets for maximum user flexibility
- Update release notes with examples for both verification methods
- Filter binary lists to exclude checksum files from combined checksums

Users can now choose between:
- Combined checksums (checksums.sha256) with --ignore-missing flag
- Individual checksums (per-binary .sha256 files) for simpler verification

This provides the best of both approaches for different user preferences.
2026-01-10 01:00:58 +01:00
Tobias Gesellchen 468fdf8836 fix: resolve artifact naming conflicts in release build
- Each build job uploads artifact with unique name (binary filename)
- Checksums job downloads all artifacts and flattens structure
- Use 'find . -type f' to only move files, avoiding directory conflicts
- Add debugging output to troubleshoot artifact structure

Fixes 'artifact with this name already exists' error that was
preventing multiple build jobs from uploading simultaneously.
2026-01-10 00:51:44 +01:00
Tobias Gesellchen 4d6423a641 fix: resolve checksums generation failure in release workflow
- Upload all binaries to single 'binaries' artifact instead of separate artifacts
- Remove complex directory flattening logic that was causing mv errors
- Add better error handling and debugging output for checksum generation
- Simplify artifact download process

Fixes the 'mv: cannot overwrite directory' errors that were causing
the Generate Checksums step to fail during release builds.
2026-01-10 00:48:20 +01:00
Tobias Gesellchen 2fcef580bb fix: prevent duplicate release workflows when creating releases via GitHub UI
- Remove push:tags trigger that duplicated release:published trigger
- Keep workflow_dispatch for manual releases
- Simplify conditional logic for release creation
- Fix tag name resolution for different event types
- Ensure single workflow run per release creation

Resolves double-triggering issue where GitHub web UI release
creation would trigger both push:tags and release:published events.
2026-01-10 00:46:52 +01:00
+153 -34
View File
@@ -1,9 +1,6 @@
name: Release
on:
push:
tags:
- "v*"
release:
types: [published]
workflow_dispatch:
@@ -13,6 +10,10 @@ on:
required: true
default: "v1.0.0"
permissions:
contents: write
actions: read
env:
GO_VERSION_FILE: "go.mod"
@@ -33,18 +34,29 @@ jobs:
- name: Validate tag format
id: version
run: |
echo "Event name: ${{ github.event_name }}"
echo "GITHUB_REF: $GITHUB_REF"
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
TAG_NAME="${{ github.event.inputs.tag }}"
echo "Using workflow_dispatch tag input"
else
TAG_NAME="${GITHUB_REF#refs/tags/}"
echo "Using GITHUB_REF tag extraction"
fi
echo "Tag name: $TAG_NAME"
echo "Tag name: '$TAG_NAME'"
echo "Tag length: ${#TAG_NAME}"
echo "Tag (hex): $(echo -n "$TAG_NAME" | od -A n -t x1)"
echo "GITHUB_REF raw: '$GITHUB_REF'"
# Validate semantic versioning format
if [[ ! "$TAG_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?$ ]]; then
echo "❌ Invalid tag format: $TAG_NAME"
echo "Expected format: v1.2.3 or v1.2.3-beta.1"
echo "Testing regex match:"
echo " Pattern: ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?\$"
echo " Input: $TAG_NAME"
exit 1
fi
@@ -135,11 +147,38 @@ jobs:
echo "Building: $OUTPUT_NAME"
# Debug: Show current state
echo "Working directory: $(pwd)"
echo "Go version: $(go version)"
echo "Files before build:"
ls -la
# Debug: Show Go cache and module cache
echo "Go build cache location: $(go env GOCACHE)"
echo "Go module cache location: $(go env GOMODCACHE)"
echo "Go build cache contents:"
ls -la "$(go env GOCACHE)" 2>/dev/null || echo "Cache directory not accessible"
echo "Go module cache contents (top level):"
ls -la "$(go env GOMODCACHE)" 2>/dev/null || echo "Module cache directory not accessible"
# Ensure clean build environment
rm -f "$OUTPUT_NAME" "$OUTPUT_NAME.sha256" "$OUTPUT_NAME.sha512"
go clean -cache
# Build with optimizations and version info
go build \
if ! go build \
-ldflags="-s -w -X main.version=v${{ needs.validate.outputs.version }} -X main.commit=${{ github.sha }} -X main.date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
-o "$OUTPUT_NAME" \
./cmd/soundtouch-cli
./cmd/soundtouch-cli; then
echo "❌ Build failed"
echo "Files after failed build:"
ls -la
exit 1
fi
# Debug: Show post-build state
echo "Files after successful build:"
ls -la
# Verify binary was created and is executable
ls -la "$OUTPUT_NAME"
@@ -148,11 +187,37 @@ jobs:
echo "binary_name=$OUTPUT_NAME" >> $GITHUB_OUTPUT
id: build
- name: Generate individual checksum
run: |
OUTPUT_NAME="${{ steps.build.outputs.binary_name }}"
# Use atomic operations to avoid conflicts
TEMP_DIR=$(mktemp -d)
echo "Building checksums for: $OUTPUT_NAME"
echo "Matrix: ${{ matrix.goos }}-${{ matrix.goarch }}"
# Generate checksums in temp directory first
sha256sum "$OUTPUT_NAME" > "${TEMP_DIR}/$(basename "$OUTPUT_NAME").sha256"
sha512sum "$OUTPUT_NAME" > "${TEMP_DIR}/$(basename "$OUTPUT_NAME").sha512"
# Move to final location atomically
mv "${TEMP_DIR}/$(basename "$OUTPUT_NAME").sha256" "$OUTPUT_NAME.sha256"
mv "${TEMP_DIR}/$(basename "$OUTPUT_NAME").sha512" "$OUTPUT_NAME.sha512"
# Cleanup
rm -rf "$TEMP_DIR"
echo "✅ Checksums generated successfully"
- name: Upload build artifact
uses: actions/upload-artifact@v6
with:
name: ${{ steps.build.outputs.binary_name }}
path: ${{ steps.build.outputs.binary_name }}
path: |
${{ steps.build.outputs.binary_name }}
${{ steps.build.outputs.binary_name }}.sha256
${{ steps.build.outputs.binary_name }}.sha512
retention-days: 1
checksums:
@@ -170,54 +235,76 @@ jobs:
run: |
cd binaries
# Flatten directory structure (artifacts are in subdirs)
find . -name "soundtouch-cli-*" -exec mv {} . \;
# Debug: Show the downloaded structure
echo "📁 Downloaded artifact structure:"
find . -type f -name "soundtouch-cli-*"
# Create a collection directory to avoid naming conflicts
mkdir -p release-files
# Move all files from subdirectories to the collection directory
find . -mindepth 2 -type f -name "soundtouch-cli-*" -exec mv {} release-files/ \;
# Remove empty directories
find . -type d -empty -delete
# Generate SHA256 checksums
sha256sum soundtouch-cli-* > checksums.sha256
# Move to the collection directory for the rest of the processing
cd release-files
# Generate SHA512 checksums
sha512sum soundtouch-cli-* > checksums.sha512
# Debug: Show flattened structure
echo "📁 Flattened structure:"
ls -la soundtouch-cli-* || echo "No files found matching pattern"
echo "📋 Generated checksums:"
cat checksums.sha256
# Generate combined checksums (exclude individual .sha256/.sha512 files)
if ls soundtouch-cli-v* 1> /dev/null 2>&1; then
# Only checksum the actual binaries, not the .sha256/.sha512 files
ls soundtouch-cli-v* | grep -v '\.sha256$' | grep -v '\.sha512$' | xargs sha256sum > checksums.sha256
ls soundtouch-cli-v* | grep -v '\.sha256$' | grep -v '\.sha512$' | xargs sha512sum > checksums.sha512
# Verify all expected files are present
EXPECTED_COUNT=7 # Based on build matrix
ACTUAL_COUNT=$(ls soundtouch-cli-* | wc -l)
echo "📋 Generated combined checksums:"
cat checksums.sha256
if [[ $ACTUAL_COUNT -ne $EXPECTED_COUNT ]]; then
echo "❌ Expected $EXPECTED_COUNT binaries, found $ACTUAL_COUNT"
# Verify all expected files are present (binaries only, not checksum files)
EXPECTED_COUNT=7 # Based on build matrix
ACTUAL_COUNT=$(ls soundtouch-cli-v* | grep -v '\.sha256$' | grep -v '\.sha512$' | wc -l)
if [[ $ACTUAL_COUNT -ne $EXPECTED_COUNT ]]; then
echo "❌ Expected $EXPECTED_COUNT binaries, found $ACTUAL_COUNT"
ls -la
exit 1
fi
echo "✅ All $ACTUAL_COUNT binaries present"
else
echo "❌ No binary files found"
echo "Directory contents:"
ls -la
exit 1
fi
echo "✅ All $ACTUAL_COUNT binaries present"
- name: Upload checksums
uses: actions/upload-artifact@v6
with:
name: checksums
path: |
binaries/checksums.sha256
binaries/checksums.sha512
binaries/release-files/checksums.sha256
binaries/release-files/checksums.sha512
binaries/release-files/*.sha256
binaries/release-files/*.sha512
retention-days: 1
- name: Upload all release assets
uses: actions/upload-artifact@v6
with:
name: release-assets
path: binaries/
path: binaries/release-files/
retention-days: 1
create_release:
name: Create GitHub Release
runs-on: ubuntu-latest
needs: [validate, checksums]
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
if: github.event_name == 'workflow_dispatch'
steps:
- name: Checkout code
@@ -234,7 +321,11 @@ jobs:
- name: Generate release notes
id: release_notes
run: |
TAG_NAME="${GITHUB_REF#refs/tags/}"
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
TAG_NAME="${{ github.event.inputs.tag }}"
else
TAG_NAME="${{ github.event.release.tag_name }}"
fi
VERSION="${TAG_NAME#v}"
# Generate comprehensive release notes
@@ -324,7 +415,34 @@ jobs:
## 🔐 Checksums
SHA256 checksums are provided in \`checksums.sha256\` to verify download integrity.
Multiple checksum options are provided for download verification:
### Combined Checksums (Recommended)
- \`checksums.sha256\` - SHA256 checksums for all binaries
- \`checksums.sha512\` - SHA512 checksums for all binaries
\`\`\`bash
# Download any binary + combined checksums
curl -L -O https://github.com/.../soundtouch-cli-v$TAG_NAME-linux-amd64
curl -L -O https://github.com/.../checksums.sha256
# Verify your specific download
sha256sum -c checksums.sha256 --ignore-missing
\`\`\`
### Individual Checksums (Per Binary)
Each binary also has its own dedicated checksum files:
- \`soundtouch-cli-v$TAG_NAME-platform.sha256\`
- \`soundtouch-cli-v$TAG_NAME-platform.sha512\`
\`\`\`bash
# Download binary + its individual checksum
curl -L -O https://github.com/.../soundtouch-cli-v$TAG_NAME-linux-amd64
curl -L -O https://github.com/.../soundtouch-cli-v$TAG_NAME-linux-amd64.sha256
# Verify with individual checksum
sha256sum -c soundtouch-cli-v$TAG_NAME-linux-amd64.sha256
\`\`\`
## 🤝 Contributing
@@ -340,13 +458,13 @@ jobs:
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.ref_name }}
name: "Bose SoundTouch Go Library ${{ github.ref_name }}"
tag_name: ${{ github.event.inputs.tag }}
name: "Bose SoundTouch Go Library ${{ github.event.inputs.tag }}"
body_path: ${{ steps.release_notes.outputs.release_notes_file }}
draft: false
prerelease: ${{ needs.validate.outputs.is_prerelease == 'true' }}
files: |
release-assets/soundtouch-cli-*
release-assets/soundtouch-cli-v*
release-assets/checksums.sha256
release-assets/checksums.sha512
fail_on_unmatched_files: true
@@ -371,7 +489,7 @@ jobs:
with:
tag_name: ${{ github.event.release.tag_name }}
files: |
release-assets/soundtouch-cli-*
release-assets/soundtouch-cli-v*
release-assets/checksums.sha256
release-assets/checksums.sha512
fail_on_unmatched_files: true
@@ -381,7 +499,7 @@ jobs:
notify:
name: Post-Release Notifications
runs-on: ubuntu-latest
needs: [validate, create_release]
needs: [validate, create_release, update_release]
if: always() && (needs.create_release.result == 'success' || needs.update_release.result == 'success')
steps:
@@ -392,7 +510,8 @@ jobs:
echo "🔐 Checksums generated and verified"
echo "📋 Release notes automatically generated"
echo ""
echo "🔗 Release URL: https://github.com/${{ github.repository }}/releases/tag/${{ github.ref_name }}"
TAG_NAME="${{ github.event.inputs.tag || github.event.release.tag_name }}"
echo "🔗 Release URL: https://github.com/${{ github.repository }}/releases/tag/${TAG_NAME}"
echo ""
echo "Next steps:"
echo "- Monitor download metrics"