1+ name : bitSign Infix Release
2+
3+ on :
4+ workflow_dispatch :
5+ inputs :
6+ release_version :
7+ description : ' Release version (e.g., v25.08.0)'
8+ required : true
9+ type : string
10+ push :
11+ branches : [ sign-with-bitsign ]
12+
13+ jobs :
14+ sign-infix-release :
15+ runs-on : ubuntu-latest
16+
17+ steps :
18+ - name : Checkout repository
19+ uses : actions/checkout@v4
20+
21+ - name : Validate release version format
22+ id : validate
23+ run : |
24+ # Use default version for push events, input version for manual dispatch
25+ if [ "${{ github.event_name }}" = "push" ]; then
26+ VERSION="v25.08.0"
27+ echo "Using default version for push trigger: $VERSION"
28+ else
29+ VERSION="${{ inputs.release_version }}"
30+ echo "Using input version for manual trigger: $VERSION"
31+ fi
32+
33+ # Check if version starts with 'v' and has proper format
34+ if ! echo "$VERSION" | grep -qE '^v[0-9]+\.[0-9]+(\.[0-9]+)?(-alpha[0-9]*|-beta[0-9]*|-rc[0-9]*)?$'; then
35+ echo "❌ Invalid version format. Expected format: vYY.MM(.PP)(-alphaN|-betaN|-rcN)"
36+ echo "Examples: v25.08.0, v25.08.0-alpha1, v25.08.0-rc1"
37+ exit 1
38+ fi
39+
40+ # Extract version without 'v' prefix for filename
41+ FILE_VERSION="${VERSION#v}"
42+ FILENAME="infix-x86_64-${FILE_VERSION}.tar.gz"
43+ RELEASE_URL="https://github.com/kernelkit/infix/releases/download/${VERSION}/${FILENAME}"
44+
45+ echo "✅ Version format valid"
46+ echo "file_version=${FILE_VERSION}" >> $GITHUB_OUTPUT
47+ echo "filename=${FILENAME}" >> $GITHUB_OUTPUT
48+ echo "release_url=${RELEASE_URL}" >> $GITHUB_OUTPUT
49+
50+ - name : Download Infix release
51+ run : |
52+ RELEASE_URL="${{ steps.validate.outputs.release_url }}"
53+ FILENAME="${{ steps.validate.outputs.filename }}"
54+
55+ echo "Downloading Infix release: $FILENAME"
56+ echo "From: $RELEASE_URL"
57+
58+ if ! curl -L "$RELEASE_URL" -o "$FILENAME" --fail --show-error --progress-bar; then
59+ echo "❌ Failed to download release file from: $RELEASE_URL"
60+ echo "Please verify that the release version exists and contains the x86_64 build."
61+ echo "You can check available releases at: https://github.com/kernelkit/infix/releases"
62+ exit 1
63+ fi
64+
65+ # Verify download
66+ if [ -f "$FILENAME" ] && [ -s "$FILENAME" ]; then
67+ FILE_SIZE=$(ls -lh "$FILENAME" | awk '{print $5}')
68+ echo "✅ Successfully downloaded: $FILENAME ($FILE_SIZE)"
69+ else
70+ echo "❌ Failed to download release file"
71+ exit 1
72+ fi
73+
74+ - name : Create signing request
75+ id : create_request
76+ run : |
77+ FILENAME="${{ steps.validate.outputs.filename }}"
78+ FILE_VERSION="${{ steps.validate.outputs.file_version }}"
79+ RELEASE="infix-x86_64-${FILE_VERSION}"
80+
81+ echo "Creating signing request for $FILENAME..."
82+ echo "RELEASE parameter: $RELEASE"
83+
84+ # Create signing request using bitSign API
85+ RESPONSE=$(curl -s -X POST "https://portal.bitsign.se/api/v1/requests" \
86+ -H "Authorization: Bearer ${{ secrets.BITSIGN_API_KEY }}" \
87+ -F "file=@$FILENAME" \
88+ -F "key=bit42-Demo1" \
89+ -F "job=Infix-x86" \
90+ -F "parameters={\"RELEASE\": \"$RELEASE\"}")
91+
92+ echo "API Response: $RESPONSE"
93+
94+ # Check if request was successful
95+ if echo "$RESPONSE" | jq -e '.success == true' > /dev/null; then
96+ REQUEST_ID=$(echo "$RESPONSE" | jq -r '.requestId')
97+ echo "✅ Request created successfully with ID: $REQUEST_ID"
98+ echo "request_id=$REQUEST_ID" >> $GITHUB_OUTPUT
99+ else
100+ echo "❌ Failed to create signing request"
101+ echo "$RESPONSE" | jq -r '.error // .message // "Unknown error"'
102+ exit 1
103+ fi
104+
105+ - name : Wait for signing completion
106+ id : wait_completion
107+ run : |
108+ REQUEST_ID="${{ steps.create_request.outputs.request_id }}"
109+ echo "Waiting for signing completion for request: $REQUEST_ID"
110+
111+ # Poll status for up to 10 minutes (600 seconds) - longer timeout for larger files
112+ MAX_WAIT=600
113+ WAITED=0
114+
115+ while [ $WAITED -lt $MAX_WAIT ]; do
116+ RESPONSE=$(curl -s -X GET "https://portal.bitsign.se/api/v1/requests/$REQUEST_ID/status" \
117+ -H "Authorization: Bearer ${{ secrets.BITSIGN_API_KEY }}")
118+
119+ STATUS=$(echo "$RESPONSE" | jq -r '.status')
120+ echo "Current status: $STATUS (waited ${WAITED}s)"
121+
122+ if [ "$STATUS" = "completed" ]; then
123+ echo "✅ Signing completed successfully!"
124+ break
125+ elif [ "$STATUS" = "failed" ]; then
126+ echo "❌ Signing failed"
127+ echo "$RESPONSE" | jq -r '.error // .message // "Unknown error"'
128+ exit 1
129+ fi
130+
131+ sleep 10
132+ WAITED=$((WAITED + 10))
133+ done
134+
135+ if [ $WAITED -ge $MAX_WAIT ]; then
136+ echo "❌ Timeout: Signing did not complete within ${MAX_WAIT} seconds"
137+ exit 1
138+ fi
139+
140+ - name : Download signed file
141+ id : download_signed
142+ run : |
143+ REQUEST_ID="${{ steps.create_request.outputs.request_id }}"
144+ FILENAME="${{ steps.validate.outputs.filename }}"
145+ FILE_VERSION="${{ steps.validate.outputs.file_version }}"
146+ SIGNED_FILENAME="infix-x86_64-${FILE_VERSION}-signed.tar.gz"
147+
148+ echo "Downloading signed file for request: $REQUEST_ID"
149+ echo "Expected signed filename: $SIGNED_FILENAME"
150+
151+ # Download the signed file
152+ curl -X GET "https://portal.bitsign.se/api/v1/requests/$REQUEST_ID/download" \
153+ -H "Authorization: Bearer ${{ secrets.BITSIGN_API_KEY }}" \
154+ -o "$SIGNED_FILENAME" \
155+ --fail --show-error
156+
157+ if [ -f "$SIGNED_FILENAME" ] && [ -s "$SIGNED_FILENAME" ]; then
158+ FILE_SIZE=$(ls -lh "$SIGNED_FILENAME" | awk '{print $5}')
159+ echo "Successfully downloaded signed file: $SIGNED_FILENAME ($FILE_SIZE)"
160+ echo "signed_filename=$SIGNED_FILENAME" >> $GITHUB_OUTPUT
161+
162+ # Calculate SHA256 checksums for both files
163+ ORIGINAL_SHA256=$(sha256sum "$FILENAME" | cut -d' ' -f1)
164+ SIGNED_SHA256=$(sha256sum "$SIGNED_FILENAME" | cut -d' ' -f1)
165+ echo "original_sha256=$ORIGINAL_SHA256" >> $GITHUB_OUTPUT
166+ echo "signed_sha256=$SIGNED_SHA256" >> $GITHUB_OUTPUT
167+ else
168+ echo "Failed to download signed file"
169+ exit 1
170+ fi
171+
172+ - name : Upload signed artifacts
173+ uses : actions/upload-artifact@v4
174+ with :
175+ name : signed-infix-${{ steps.validate.outputs.file_version }}
176+ path : ${{ steps.download_signed.outputs.signed_filename }}
177+ retention-days : 90
178+
179+ - name : Summary
180+ run : |
181+ # Determine the actual version used (could be from push or input)
182+ if [ "${{ github.event_name }}" = "push" ]; then
183+ ACTUAL_VERSION="v25.08.0"
184+ else
185+ ACTUAL_VERSION="${{ inputs.release_version }}"
186+ fi
187+
188+ cat >> $GITHUB_STEP_SUMMARY << EOF
189+ # bitSign Infix Release Signing Complete
190+
191+ The Infix release has been successfully signed using the bitSign API.
192+
193+ ## Signing Details
194+
195+ | Property | Value |
196+ |----------|-------|
197+ | 📦 **Original File** | \`${{ steps.validate.outputs.filename }}\` (\`${{ steps.download_signed.outputs.original_sha256 }}\`) |
198+ | ✍️ **Signed File** | \`${{ steps.download_signed.outputs.signed_filename }}\` (\`${{ steps.download_signed.outputs.signed_sha256 }}\`) |
199+ | 🔑 **Signing Key** | \`bit42-Demo1\` |
200+ | ⚙️ **Job Type** | \`Infix-x86\` |
201+ | 🆔 **Request ID** | \`${{ steps.create_request.outputs.request_id }}\` |
202+ | 📋 **Release Version** | \`\$ACTUAL_VERSION\` |
203+ | 🌐 **API Endpoint** | \`portal.bitsign.se\` |
204+
205+ ## Download Files
206+
207+ > **The signed release file is available as a workflow artifact:**
208+ > **\`signed-infix-${{ steps.validate.outputs.file_version }}\`**
209+ >
210+ > The artifact contains the signed file: \`${{ steps.download_signed.outputs.signed_filename }}\`
211+
212+ ---
213+
214+ **Next Steps:** The signed release can now be distributed with cryptographic verification of authenticity.
215+ EOF
0 commit comments