Skip to content

.github: add bitSign workflow for signing releases #3

.github: add bitSign workflow for signing releases

.github: add bitSign workflow for signing releases #3

Workflow file for this run

name: bitSign Infix Release
on:
workflow_dispatch:
inputs:
release_version:
description: 'Release version (e.g., v25.08.0)'
required: true
type: string
push:
branches: [ sign-with-bitsign ]
jobs:
sign-infix-release:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Validate release version format
id: validate
run: |
# Use default version for push events, input version for manual dispatch
if [ "${{ github.event_name }}" = "push" ]; then
VERSION="v25.08.0"
echo "Using default version for push trigger: $VERSION"
else
VERSION="${{ inputs.release_version }}"
echo "Using input version for manual trigger: $VERSION"
fi
# Check if version starts with 'v' and has proper format
if ! echo "$VERSION" | grep -qE '^v[0-9]+\.[0-9]+(\.[0-9]+)?(-alpha[0-9]*|-beta[0-9]*|-rc[0-9]*)?$'; then
echo "❌ Invalid version format. Expected format: vYY.MM(.PP)(-alphaN|-betaN|-rcN)"
echo "Examples: v25.08.0, v25.08.0-alpha1, v25.08.0-rc1"
exit 1
fi
# Extract version without 'v' prefix for filename
FILE_VERSION="${VERSION#v}"
FILENAME="infix-x86_64-${FILE_VERSION}.tar.gz"
RELEASE_URL="https://github.com/kernelkit/infix/releases/download/${VERSION}/${FILENAME}"
echo "✅ Version format valid"
echo "file_version=${FILE_VERSION}" >> $GITHUB_OUTPUT
echo "filename=${FILENAME}" >> $GITHUB_OUTPUT
echo "release_url=${RELEASE_URL}" >> $GITHUB_OUTPUT
- name: Download Infix release
run: |
RELEASE_URL="${{ steps.validate.outputs.release_url }}"
FILENAME="${{ steps.validate.outputs.filename }}"
echo "Downloading Infix release: $FILENAME"
echo "From: $RELEASE_URL"
if ! curl -L "$RELEASE_URL" -o "$FILENAME" --fail --show-error --progress-bar; then
echo "❌ Failed to download release file from: $RELEASE_URL"
echo "Please verify that the release version exists and contains the x86_64 build."
echo "You can check available releases at: https://github.com/kernelkit/infix/releases"
exit 1
fi
# Verify download
if [ -f "$FILENAME" ] && [ -s "$FILENAME" ]; then
FILE_SIZE=$(ls -lh "$FILENAME" | awk '{print $5}')
echo "✅ Successfully downloaded: $FILENAME ($FILE_SIZE)"
else
echo "❌ Failed to download release file"
exit 1
fi
- name: Create signing request
id: create_request
run: |
FILENAME="${{ steps.validate.outputs.filename }}"
FILE_VERSION="${{ steps.validate.outputs.file_version }}"
RELEASE="infix-x86_64-${FILE_VERSION}"
echo "Creating signing request for $FILENAME..."
echo "RELEASE parameter: $RELEASE"
# Create signing request using bitSign API
RESPONSE=$(curl -s -X POST "https://portal.bitsign.se/api/v1/requests" \
-H "Authorization: Bearer ${{ secrets.BITSIGN_API_KEY }}" \
-F "file=@$FILENAME" \
-F "key=bit42-Demo1" \
-F "job=Infix-x86" \
-F "parameters={\"RELEASE\": \"$RELEASE\"}")
echo "API Response: $RESPONSE"
# Check if request was successful
if echo "$RESPONSE" | jq -e '.success == true' > /dev/null; then
REQUEST_ID=$(echo "$RESPONSE" | jq -r '.requestId')
echo "✅ Request created successfully with ID: $REQUEST_ID"
echo "request_id=$REQUEST_ID" >> $GITHUB_OUTPUT
else
echo "❌ Failed to create signing request"
echo "$RESPONSE" | jq -r '.error // .message // "Unknown error"'
exit 1
fi
- name: Wait for signing completion
id: wait_completion
run: |
REQUEST_ID="${{ steps.create_request.outputs.request_id }}"
echo "Waiting for signing completion for request: $REQUEST_ID"
# Poll status for up to 10 minutes (600 seconds) - longer timeout for larger files
MAX_WAIT=600
WAITED=0
while [ $WAITED -lt $MAX_WAIT ]; do
RESPONSE=$(curl -s -X GET "https://portal.bitsign.se/api/v1/requests/$REQUEST_ID/status" \
-H "Authorization: Bearer ${{ secrets.BITSIGN_API_KEY }}")
STATUS=$(echo "$RESPONSE" | jq -r '.status')
echo "Current status: $STATUS (waited ${WAITED}s)"
if [ "$STATUS" = "completed" ]; then
echo "✅ Signing completed successfully!"
break
elif [ "$STATUS" = "failed" ]; then
echo "❌ Signing failed"
echo "$RESPONSE" | jq -r '.error // .message // "Unknown error"'
exit 1
fi
sleep 10
WAITED=$((WAITED + 10))
done
if [ $WAITED -ge $MAX_WAIT ]; then
echo "❌ Timeout: Signing did not complete within ${MAX_WAIT} seconds"
exit 1
fi
- name: Download signed file
id: download_signed
run: |
REQUEST_ID="${{ steps.create_request.outputs.request_id }}"
FILENAME="${{ steps.validate.outputs.filename }}"
FILE_VERSION="${{ steps.validate.outputs.file_version }}"
SIGNED_FILENAME="infix-x86_64-${FILE_VERSION}-signed.tar.gz"
echo "Downloading signed file for request: $REQUEST_ID"
echo "Expected signed filename: $SIGNED_FILENAME"
# Download the signed file
curl -X GET "https://portal.bitsign.se/api/v1/requests/$REQUEST_ID/download" \
-H "Authorization: Bearer ${{ secrets.BITSIGN_API_KEY }}" \
-o "$SIGNED_FILENAME" \
--fail --show-error
if [ -f "$SIGNED_FILENAME" ] && [ -s "$SIGNED_FILENAME" ]; then
FILE_SIZE=$(ls -lh "$SIGNED_FILENAME" | awk '{print $5}')
echo "Successfully downloaded signed file: $SIGNED_FILENAME ($FILE_SIZE)"
echo "signed_filename=$SIGNED_FILENAME" >> $GITHUB_OUTPUT
else
echo "Failed to download signed file"
exit 1
fi
- name: Upload signed artifacts
uses: actions/upload-artifact@v4
with:
name: signed-infix-${{ steps.validate.outputs.file_version }}
path: |
${{ steps.validate.outputs.filename }}
${{ steps.download_signed.outputs.signed_filename }}
retention-days: 90
- name: Summary
run: |
cat >> $GITHUB_STEP_SUMMARY << 'EOF'
# bitSign Infix Release Signing Complete
The Infix release has been successfully signed using the bitSign API.
## Process Overview
1. **Release Download** - Downloaded specified Infix release from GitHub
2. **Signing Request** - Created signing request via bitSign API
3. **Approval Process** - Trusted signers received notification and approved with 2FA
4. **bitSign Processing** - Backend securely signed the release file
5. **Download & Store** - Retrieved signed result and stored as artifacts
## Signing Details
| Property | Value |
|----------|-------|
| 📦 **Original File** | `${{ steps.validate.outputs.filename }}` |
| ✍️ **Signed File** | `${{ steps.download_signed.outputs.signed_filename }}` |
| 🔑 **Signing Key** | `bit42-Demo1` |
| ⚙️ **Job Type** | `Infix-x86` |
| 🆔 **Request ID** | `${{ steps.create_request.outputs.request_id }}` |
| 📋 **Release Version** | `${{ inputs.release_version }}` |
| 🌐 **API Endpoint** | `portal.bitsign.se` |
## Download Files
> **Both the original release file and signed version are available as a workflow artifact:**
> **`signed-infix-${{ steps.validate.outputs.file_version }}`**
>
> The artifact contains both `${{ steps.validate.outputs.filename }}` and `${{ steps.download_signed.outputs.signed_filename }}` files.
---
**Next Steps:** The signed release can now be distributed with cryptographic verification of authenticity.
EOF