Pulse/.github/workflows/release.yml
rcourtman fa8a8f3af3 Reduce release assets by removing duplicates
Removed:
- Individual .sha256 files (checksums.txt already contains all checksums)
- Standalone binaries without version numbers (users should download versioned tarballs/zips)

Standalone binaries are only needed in Docker images for the /download/ endpoint.
GitHub releases should only contain versioned archives for user downloads.

This reduces release assets from ~54 files to ~19 files per release.
2025-11-11 17:26:00 +00:00

289 lines
10 KiB
YAML

name: Release
on:
workflow_dispatch:
inputs:
version:
description: 'Version number (e.g., 4.28.1)'
required: true
type: string
jobs:
build-docker-images:
runs-on: ubuntu-latest
timeout-minutes: 60
permissions:
contents: read
packages: write
outputs:
tag: ${{ steps.set_version.outputs.tag }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set version output
id: set_version
run: |
VERSION="${{ inputs.version }}"
TAG="v${VERSION}"
echo "tag=${TAG}" >> $GITHUB_OUTPUT
echo "Building Docker images for ${TAG}..."
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Pulse server image
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
provenance: false
tags: |
rcourtman/pulse:latest
rcourtman/pulse:${{ steps.set_version.outputs.tag }}
ghcr.io/${{ github.repository_owner }}/pulse:latest
ghcr.io/${{ github.repository_owner }}/pulse:${{ steps.set_version.outputs.tag }}
labels: |
org.opencontainers.image.title=Pulse
org.opencontainers.image.description=Proxmox monitoring system
org.opencontainers.image.version=${{ steps.set_version.outputs.tag }}
org.opencontainers.image.created=${{ github.event.repository.updated_at }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
org.opencontainers.image.url=${{ github.server_url }}/${{ github.repository }}
org.opencontainers.image.licenses=MIT
- name: Build and push Docker agent image
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
target: agent_runtime
platforms: linux/amd64,linux/arm64
push: true
provenance: false
tags: |
rcourtman/pulse-docker-agent:latest
rcourtman/pulse-docker-agent:${{ steps.set_version.outputs.tag }}
ghcr.io/${{ github.repository_owner }}/pulse-docker-agent:latest
ghcr.io/${{ github.repository_owner }}/pulse-docker-agent:${{ steps.set_version.outputs.tag }}
labels: |
org.opencontainers.image.title=Pulse Docker Agent
org.opencontainers.image.description=Docker container monitoring agent for Pulse
org.opencontainers.image.version=${{ steps.set_version.outputs.tag }}
org.opencontainers.image.created=${{ github.event.repository.updated_at }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
org.opencontainers.image.url=${{ github.server_url }}/${{ github.repository }}
org.opencontainers.image.licenses=MIT
- name: Output Docker image information
run: |
echo "✅ Docker images built and pushed successfully!"
echo ""
echo "Server images:"
echo " - rcourtman/pulse:${{ steps.set_version.outputs.tag }}"
echo " - rcourtman/pulse:latest"
echo ""
echo "Agent images:"
echo " - rcourtman/pulse-docker-agent:${{ steps.set_version.outputs.tag }}"
echo " - rcourtman/pulse-docker-agent:latest"
create-release:
needs: build-docker-images
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history for tags
- name: Fetch all tags
run: git fetch --tags --force
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.24'
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: |
# Install zip for Windows binaries
sudo apt-get update
sudo apt-get install -y zip
# Install Helm for chart packaging
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
- name: Build release artifacts
run: |
echo "Building release v${{ inputs.version }}..."
./scripts/build-release.sh ${{ inputs.version }}
- name: Validate release artifacts
run: |
echo "Validating release v${{ inputs.version }}..."
# Note: Docker image validation is skipped in this workflow
# since we're only validating the built artifacts (tarballs, binaries, checksums)
# Docker images were built and validated in previous job
# Run validation with --skip-docker flag
./scripts/validate-release.sh ${{ inputs.version }} --skip-docker || {
echo "❌ Release validation failed!"
echo "The workflow will now fail. No release will be created."
exit 1
}
- name: Generate release notes
id: generate_notes
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: |
echo "Generating release notes using LLM..."
# Find previous release tag (simply get the latest tag)
PREVIOUS_TAG=$(git tag --sort=-version:refname | head -1)
if [ -z "$PREVIOUS_TAG" ]; then
echo "No previous tag found, comparing with first commit"
PREVIOUS_TAG=$(git rev-list --max-parents=0 HEAD)
fi
echo "Comparing v${{ inputs.version }} with ${PREVIOUS_TAG}..."
# Generate notes - script writes output between separator lines
TEMP_OUTPUT=$(mktemp)
# Run script, capture exit code (don't fail immediately)
set +e
./scripts/generate-release-notes.sh ${{ inputs.version }} "${PREVIOUS_TAG}" > "$TEMP_OUTPUT" 2>&1
SCRIPT_EXIT=$?
set -e
if [ $SCRIPT_EXIT -ne 0 ]; then
echo "❌ Release notes generation failed:"
cat "$TEMP_OUTPUT"
rm -f "$TEMP_OUTPUT"
exit 1
fi
# Extract notes between separator lines (everything between the two ━━━ lines)
RELEASE_NOTES=$(awk '/^Generated release notes:/{flag=1;next}/^━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━$/{if(flag==1){flag=2}else if(flag==2){flag=3}}flag==2' "$TEMP_OUTPUT")
rm -f "$TEMP_OUTPUT"
# Save to output (escape for GitHub Actions multiline)
echo "RELEASE_NOTES<<EOF" >> $GITHUB_OUTPUT
echo "$RELEASE_NOTES" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
echo "✅ Release notes generated successfully"
- name: Create draft release
id: create_release
env:
GH_TOKEN: ${{ github.token }}
run: |
VERSION="${{ inputs.version }}"
TAG="v${VERSION}"
echo "Creating draft release for ${TAG}..."
# Write release notes directly from GitHub output to file
# This avoids bash interpreting backticks in the markdown
NOTES_FILE=$(mktemp)
cat <<'NOTES_EOF' > "$NOTES_FILE"
${{ steps.generate_notes.outputs.RELEASE_NOTES }}
NOTES_EOF
# Create draft release with generated notes
gh release create "${TAG}" \
--draft \
--title "Pulse ${TAG}" \
--notes-file "$NOTES_FILE"
rm -f "$NOTES_FILE"
echo "release_url=$(gh release view ${TAG} --json url -q .url)" >> $GITHUB_OUTPUT
echo "tag=${TAG}" >> $GITHUB_OUTPUT
- name: Upload checksums.txt
env:
GH_TOKEN: ${{ github.token }}
run: |
TAG="${{ steps.create_release.outputs.tag }}"
echo "Uploading checksums.txt..."
gh release upload "${TAG}" release/checksums.txt
- name: Upload release assets
env:
GH_TOKEN: ${{ github.token }}
run: |
TAG="${{ steps.create_release.outputs.tag }}"
echo "Uploading release assets..."
# Upload tarballs
gh release upload "${TAG}" release/*.tar.gz
# Upload Windows zip files
gh release upload "${TAG}" release/*.zip
# Upload Helm chart if it exists
if ls release/*.tgz 1> /dev/null 2>&1; then
echo "Uploading Helm chart..."
gh release upload "${TAG}" release/*.tgz
fi
# Upload install.sh
gh release upload "${TAG}" release/install.sh
- name: Output release information
run: |
echo "✅ Release draft created successfully!"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📦 Release: ${{ steps.create_release.outputs.tag }}"
echo "🔗 URL: ${{ steps.create_release.outputs.release_url }}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "⚠️ IMPORTANT: This release is in DRAFT status"
echo ""
echo "Next steps:"
echo "1. Review the release at the URL above"
echo "2. Update the release notes with changes since last release"
echo "3. Publish the release manually when ready"
echo ""
echo "All artifacts have been uploaded and validated."
echo "Docker images are available at Docker Hub and GHCR."
echo "checksums.txt matches all uploaded binaries."
echo ""