-
Notifications
You must be signed in to change notification settings - Fork 432
309 lines (274 loc) · 14.8 KB
/
release-fleetd-base.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
name: Release and upload fleetd base to https://download.fleetdm.com
# This workflow checks TUF if there are updates to orbit, desktop, and osqueryd components of fleetd.
# If there are updates, it builds and uploads the following files:
# - stable/meta.json
# - stable/tuf-meta.json
# - stable/fleetd-base.pkg
# - stable/fleetd-base-manifest.plist
# - stable/fleetd-base.msi
# - archive/stable/YYYY-MM-DD_HH-MM-SS/meta.json
# - archive/stable/YYYY-MM-DD_HH-MM-SS/tuf-meta.json
# - archive/stable/YYYY-MM-DD_HH-MM-SS/fleetd-base.pkg
# - archive/stable/YYYY-MM-DD_HH-MM-SS/fleetd-base-manifest.plist
# - archive/stable/YYYY-MM-DD_HH-MM-SS/fleetd-base.msi
# Finally, it verifies the uploaded installers and their checksums.
on:
pull_request:
workflow_dispatch: # Manual
schedule:
- cron: '0 3 * * *' # Nightly 3AM UTC
# This allows a subsequently queued workflow run to interrupt previous runs
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id}}
cancel-in-progress: true
defaults:
run:
# fail-fast using bash -eo pipefail. See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#exit-codes-and-error-action-preference
shell: bash
permissions:
contents: read
env:
R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }}
R2_ACCESS_KEY_ID: ${{ secrets.R2_DOWNLOAD_TESTING_ACCESS_KEY_ID }} # Production: ${{ secrets.R2_DOWNLOAD_ACCESS_KEY_ID }} | Testing: ${{ secrets.R2_DOWNLOAD_TESTING_ACCESS_KEY_ID }}
R2_ACCESS_KEY_SECRET: ${{ secrets.R2_DOWNLOAD_TESTING_ACCESS_KEY_SECRET }} # Production: ${{ secrets.R2_DOWNLOAD_ACCESS_KEY_SECRET }} | Testing: ${{ secrets.R2_DOWNLOAD_TESTING_ACCESS_KEY_SECRET }}
R2_BUCKET: download-testing # Production: download | Testing: download-testing
BASE_URL: https://download-testing.fleetdm.com # Production: https://download.fleetdm.com | Testing: https://download-testing.fleetdm.com
jobs:
check-for-fleetd-component-updates:
runs-on: ubuntu-latest
outputs:
date_dir: ${{ steps.check-for-fleetd-component-updates.outputs.date_dir }}
update_needed: ${{ steps.check-for-fleetd-component-updates.outputs.update_needed }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0
with:
egress-policy: audit
- name: Checkout Code
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
fetch-depth: 0
- name: Install Go
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
with:
go-version-file: 'go.mod'
- name: Check for fleetd component updates
id: check-for-fleetd-component-updates
run: |
go run tools/tuf/status/tuf-status.go channel-version -channel stable --components orbit,desktop,osqueryd --format json > latest-tuf-meta.json
: # Check that latest-tuf-meta.json is valid
jq -e . >/dev/null 2>&1 <<< $(cat latest-tuf-meta.json)
: # Download the current TUF meta file in order to compare it with the latest
curl -O $BASE_URL/stable/tuf-meta.json
echo "update_needed=true" >> $GITHUB_OUTPUT
echo "date_dir=$(date -u +%Y-%m-%d_%H-%M-%S)" >> $GITHUB_OUTPUT
- name: Upload latest TUF meta artifact
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
with:
name: latest-tuf-meta.json
path: latest-tuf-meta.json
update-fleetd-base-pkg:
needs: [check-for-fleetd-component-updates]
if: needs.check-for-fleetd-component-updates.outputs.update_needed == 'true'
runs-on: macos-latest
outputs:
fleetd_base_pkg_sha256: ${{ steps.build-sign-notarize.outputs.fleetd_base_pkg_sha256 }}
env:
FULL_DATE_DIR: archive/stable/${{ needs.check-for-fleetd-component-updates.outputs.date_dir }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0
with:
egress-policy: audit
- name: Checkout code needed for R2 upload
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
sparse-checkout: |
.github/actions/r2-upload/action.yml
.github/scripts/rclone-install.sh
sparse-checkout-cone-mode: false
- name: Install fleetctl
run: npm install -g fleetctl
- name: Import package signing keys
env:
APPLE_INSTALLER_CERTIFICATE: ${{ secrets.APPLE_INSTALLER_CERTIFICATE }}
APPLE_INSTALLER_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_INSTALLER_CERTIFICATE_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
echo "$APPLE_INSTALLER_CERTIFICATE" | base64 --decode > certificate.p12
security create-keychain -p $KEYCHAIN_PASSWORD build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p $KEYCHAIN_PASSWORD build.keychain
security import certificate.p12 -k build.keychain -P $APPLE_INSTALLER_CERTIFICATE_PASSWORD -T /usr/bin/productsign
security set-key-partition-list -S apple-tool:,apple:,productsign: -s -k $KEYCHAIN_PASSWORD build.keychain
security find-identity -vv
rm certificate.p12
- name: Build PKG, sign, and notarize
id: build-sign-notarize
env:
AC_USERNAME: ${{ secrets.APPLE_USERNAME }}
AC_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
AC_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
PACKAGE_SIGNING_IDENTITY_SHA1: D52080FD1F0941DE31346F06DA0F08AED6FACBBF
run: |
fleetctl package --type pkg --fleet-desktop --use-system-configuration --sign-identity $PACKAGE_SIGNING_IDENTITY_SHA1 --notarize --update-roots='{"signed":{"_type":"root","spec_version":"1.0","version":1,"expires":"2034-09-21T10:15:42-04:00","keys":{"12d797bd81d8a13d586b9eee0b230a2106d92ac4b78f80c1930e74869b37f442":{"keytype":"ed25519","scheme":"ed25519","keyid_hash_algorithms":["sha256","sha512"],"keyval":{"public":"f07715647d065f8c938b465134b16fb1524817c4ab3536c88b5210b2101af55c"}},"21155f3fd917bb48ab6d1e34646196cde398ce76f4e515c254e7ae6328353cd5":{"keytype":"ed25519","scheme":"ed25519","keyid_hash_algorithms":["sha256","sha512"],"keyval":{"public":"85349354a7958c843dc3afd97d08d5484a9e9e4454df00b7decd5f69e237b6bb"}},"522fbc30ded293b2dbb92c4d649d34950714fb1d0ba23f3f15b81d47608fe9bb":{"keytype":"ed25519","scheme":"ed25519","keyid_hash_algorithms":["sha256","sha512"],"keyval":{"public":"05fdc5ef5bc7301c8f4465b0c048b8ef7f9c1083a0c5b5717f603652e1c5c6ca"}},"a1312aa69ec097c463db3f142aa0dacef2a38e73874a37f5dd4921c8e23a8956":{"keytype":"ed25519","scheme":"ed25519","keyid_hash_algorithms":["sha256","sha512"],"keyval":{"public":"2e713e869728c940234be69fa7b55e98b5504dbd17acc1b434b6525f4213d810"}}},"roles":{"root":{"keyids":["a1312aa69ec097c463db3f142aa0dacef2a38e73874a37f5dd4921c8e23a8956"],"threshold":1},"snapshot":{"keyids":["21155f3fd917bb48ab6d1e34646196cde398ce76f4e515c254e7ae6328353cd5"],"threshold":1},"targets":{"keyids":["12d797bd81d8a13d586b9eee0b230a2106d92ac4b78f80c1930e74869b37f442"],"threshold":1},"timestamp":{"keyids":["522fbc30ded293b2dbb92c4d649d34950714fb1d0ba23f3f15b81d47608fe9bb"],"threshold":1}},"consistent_snapshot":false},"signatures":[{"keyid":"a1312aa69ec097c463db3f142aa0dacef2a38e73874a37f5dd4921c8e23a8956","sig":"1756739aa03b294ed3007af0449aa072e0f74865ffe0b8d7cb9449119af9abf08008abf426fa6f8b60805214460627032504c12593eee1938d6b48fa7ba07a07"}]}' --update-url=https://jve-images-snicket.ngrok.app
mv fleet-osquery*.pkg fleetd-base.pkg
: # Calculate the SHA256 checksum of the package
echo "fleetd_base_pkg_sha256=$(shasum -a 256 fleetd-base.pkg | cut -d ' ' -f 1)" >> $GITHUB_OUTPUT
- name: Create plist
run: |
echo '<plist version="1.0">
<dict>
<key>items</key>
<array>
<dict>
<key>assets</key>
<array>
<dict>
<key>kind</key>
<string>software-package</string>
<key>sha256-size</key>
<integer>32</integer>
<key>sha256s</key>
<array>
<string>${{ steps.build-sign-notarize.outputs.fleetd_base_pkg_sha256 }}</string>
</array>
<key>url</key>
<string>${{ env.BASE_URL }}/${{ env.FULL_DATE_DIR }}/fleetd-base.pkg</string>
</dict>
</array>
</dict>
</array>
</dict>
</plist>' > fleetd-base-manifest.plist
- name: Set up files and directories for R2 upload
run: |
mkdir -p stable
mkdir -p ${{ env.FULL_DATE_DIR }}
cp fleetd-base.pkg stable/
cp fleetd-base-manifest.plist stable/
cp fleetd-base.pkg ${{ env.FULL_DATE_DIR }}/
cp fleetd-base-manifest.plist ${{ env.FULL_DATE_DIR }}/
- name: Upload package
uses: ./.github/actions/r2-upload
with:
filenames: stable/fleetd-base.pkg,stable/fleetd-base-manifest.plist,${{ env.FULL_DATE_DIR }}/fleetd-base.pkg,${{ env.FULL_DATE_DIR }}/fleetd-base-manifest.plist
build-fleetd-base-msi:
needs: [check-for-fleetd-component-updates]
if: needs.check-for-fleetd-component-updates.outputs.update_needed == 'true'
runs-on: ubuntu-latest
env:
FULL_DATE_DIR: archive/stable/${{ needs.check-for-fleetd-component-updates.outputs.date_dir }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0
with:
egress-policy: audit
- name: Install fleetctl
run: npm install -g fleetctl
- name: Build MSI
id: build
run: |
fleetctl package --type msi --fleet-desktop --fleet-url dummy --enroll-secret dummy
mv fleet-osquery*.msi fleetd-base.msi
- name: Upload fleetd-base.msi for code signing
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # 4.3.3
with:
name: unsigned-windows
path: fleetd-base.msi
code-sign-windows:
needs: build-fleetd-base-msi
uses: ./.github/workflows/code-sign-windows.yml
with:
filename: fleetd-base.msi
upload_name: fleetd-base-msi
secrets:
DIGICERT_KEYLOCKER_CERTIFICATE: ${{ secrets.DIGICERT_KEYLOCKER_CERTIFICATE }}
DIGICERT_KEYLOCKER_PASSWORD: ${{ secrets.DIGICERT_KEYLOCKER_PASSWORD }}
DIGICERT_KEYLOCKER_HOST_URL: ${{ secrets.DIGICERT_KEYLOCKER_HOST_URL }}
DIGICERT_API_KEY: ${{ secrets.DIGICERT_API_KEY }}
DIGICERT_KEYLOCKER_CERTIFICATE_FINGERPRINT: ${{ secrets.DIGICERT_KEYLOCKER_CERTIFICATE_FINGERPRINT }}
update-fleetd-base-msi:
needs: [code-sign-windows, check-for-fleetd-component-updates]
runs-on: ubuntu-latest
outputs:
fleetd_base_msi_sha256: ${{ steps.prepare-files.outputs.fleetd_base_msi_sha256 }}
env:
FULL_DATE_DIR: archive/stable/${{ needs.check-for-fleetd-component-updates.outputs.date_dir }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0
with:
egress-policy: audit
- name: Checkout code needed for R2 upload
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
sparse-checkout: |
.github/actions/r2-upload/action.yml
.github/scripts/rclone-install.sh
sparse-checkout-cone-mode: false
- name: Download signed artifact
uses: actions/download-artifact@9c19ed7fe5d278cd354c7dfd5d3b88589c7e2395 # v4.1.6
with:
name: fleetd-base-msi
- name: Prepare files for R2 upload
id: prepare-files
run: |
mkdir -p stable
mkdir -p ${{ env.FULL_DATE_DIR }}
cp fleetd-base.msi stable/
cp fleetd-base.msi ${{ env.FULL_DATE_DIR }}/
: # Calculate the SHA256 checksum of the package
echo "fleetd_base_msi_sha256=$(shasum -a 256 fleetd-base.msi | cut -d ' ' -f 1)" >> $GITHUB_OUTPUT
- name: Upload package
uses: ./.github/actions/r2-upload
with:
filenames: stable/fleetd-base.msi,${{ env.FULL_DATE_DIR }}/fleetd-base.msi
update-meta-files:
needs: [check-for-fleetd-component-updates, update-fleetd-base-pkg, update-fleetd-base-msi]
runs-on: ubuntu-latest
env:
FULL_DATE_DIR: archive/stable/${{ needs.check-for-fleetd-component-updates.outputs.date_dir }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0
with:
egress-policy: audit
- name: Checkout code needed for R2 upload
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
sparse-checkout: |
.github/actions/r2-upload/action.yml
.github/scripts/rclone-install.sh
sparse-checkout-cone-mode: false
- name: Download latest-tuf-meta.json artifact
uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
with:
name: latest-tuf-meta.json
- name: Set up files and directories for R2 upload
run: |
mkdir -p stable
mkdir -p ${{ env.FULL_DATE_DIR }}
echo '{
"fleetd_base_msi_url": "${{ env.BASE_URL }}/${{ env.FULL_DATE_DIR }}/fleetd-base.msi",
"fleetd_base_msi_sha256": "${{ needs.update-fleetd-base-msi.outputs.fleetd_base_msi_sha256 }}",
"fleetd_base_pkg_url": "${{ env.BASE_URL }}/${{ env.FULL_DATE_DIR }}/fleetd-base.pkg",
"fleetd_base_pkg_sha256": "${{ needs.update-fleetd-base-pkg.outputs.fleetd_base_pkg_sha256 }}",
"fleetd_base_manifest_plist_url": "${{ env.BASE_URL }}/${{ env.FULL_DATE_DIR }}/fleetd-base-manifest.plist",
"version": "${{ needs.check-for-fleetd-component-updates.outputs.date_dir }}"
}' > meta.json
: # Check that meta.json is valid
jq -e . >/dev/null 2>&1 <<< $(cat meta.json)
cp latest-tuf-meta.json stable/tuf-meta.json
cp latest-tuf-meta.json ${{ env.FULL_DATE_DIR }}/tuf-meta.json
cp meta.json stable/meta.json
cp meta.json ${{ env.FULL_DATE_DIR }}/meta.json
- name: Upload meta files
uses: ./.github/actions/r2-upload
with:
filenames: stable/meta.json,stable/tuf-meta.json,${{ env.FULL_DATE_DIR }}/meta.json,${{ env.FULL_DATE_DIR }}/tuf-meta.json
verify-fleetd-base:
needs: update-meta-files
uses: ./.github/workflows/verify-fleetd-base.yml
with:
base-url: "https://download-testing.fleetdm.com" # Production: "https://download.fleetdm.com" | Testing: "https://download-testing.fleetdm.com"