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
+ else
162
+ echo "Failed to download signed file"
163
+ exit 1
164
+ fi
165
+
166
+ - name : Upload signed artifacts
167
+ uses : actions/upload-artifact@v4
168
+ with :
169
+ name : signed-infix-${{ steps.validate.outputs.file_version }}
170
+ path : |
171
+ ${{ steps.validate.outputs.filename }}
172
+ ${{ steps.download_signed.outputs.signed_filename }}
173
+ retention-days : 90
174
+
175
+ - name : Summary
176
+ run : |
177
+ cat >> $GITHUB_STEP_SUMMARY << 'EOF'
178
+ # bitSign Infix Release Signing Complete
179
+
180
+ The Infix release has been successfully signed using the bitSign API.
181
+
182
+ ## Process Overview
183
+
184
+ 1. **Release Download** - Downloaded specified Infix release from GitHub
185
+ 2. **Signing Request** - Created signing request via bitSign API
186
+ 3. **Approval Process** - Trusted signers received notification and approved with 2FA
187
+ 4. **bitSign Processing** - Backend securely signed the release file
188
+ 5. **Download & Store** - Retrieved signed result and stored as artifacts
189
+
190
+ ## Signing Details
191
+
192
+ | Property | Value |
193
+ |----------|-------|
194
+ | 📦 **Original File** | `${{ steps.validate.outputs.filename }}` |
195
+ | ✍️ **Signed File** | `${{ steps.download_signed.outputs.signed_filename }}` |
196
+ | 🔑 **Signing Key** | `bit42-Demo1` |
197
+ | ⚙️ **Job Type** | `Infix-x86` |
198
+ | 🆔 **Request ID** | `${{ steps.create_request.outputs.request_id }}` |
199
+ | 📋 **Release Version** | `${{ inputs.release_version }}` |
200
+ | 🌐 **API Endpoint** | `portal.bitsign.se` |
201
+
202
+ ## Download Files
203
+
204
+ > **Both the original release file and signed version are available as a workflow artifact:**
205
+ > **`signed-infix-${{ steps.validate.outputs.file_version }}`**
206
+ >
207
+ > The artifact contains both `${{ steps.validate.outputs.filename }}` and `${{ steps.download_signed.outputs.signed_filename }}` files.
208
+
209
+ ---
210
+
211
+ **Next Steps:** The signed release can now be distributed with cryptographic verification of authenticity.
212
+ EOF
0 commit comments