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