-
Notifications
You must be signed in to change notification settings - Fork 0
161 lines (143 loc) · 6.05 KB
/
Copy pathrelease.yml
File metadata and controls
161 lines (143 loc) · 6.05 KB
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
# Tag v1.2.3 -> build every target, sign the Windows artifacts, publish a
# GitHub release.
#
# The build job is deliberately separate from signing and publishing. That is
# the shape SignPath Foundation (and any other signing service) requires: the
# thing that gets signed must be an artifact of a specific, inspectable CI
# run, not something a maintainer uploaded from a laptop. Splitting the jobs
# is what makes the provenance checkable.
#
# THE SIGNING JOB IS INERT UNTIL THE PROJECT HAS A CERTIFICATE. It is guarded
# on the SIGNPATH_ORGANIZATION_ID repository variable, so until that is set
# the release publishes unsigned artifacts and says so. See
# docs/signing/signpath-application.md for where the certificate comes from
# and why FOG has never had a publicly trusted one.
name: Release
on:
push:
tags: ['v*']
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
# Tags and full history: build/msi.sh turns the tag into the MSI's
# numeric ProductVersion, and falls back to a commit count without
# them -- so a shallow checkout would publish v1.2.3 as 0.0.0.
fetch-depth: 0
- uses: actions/setup-go@v7
with:
go-version-file: go.mod
check-latest: true
- name: install msitools and wixl
run: |
sudo apt-get update
sudo apt-get install --no-install-recommends -y msitools wixl
- name: install goversioninfo
run: go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo@v1.7.0
- name: test before shipping
run: go test ./... -count=1
- name: cross-compile every target
run: ./build/cross.sh "${GITHUB_REF_NAME}"
- name: build the Windows installer
run: ./build/msi.sh "${GITHUB_REF_NAME}"
# Checksums are produced here, over the unsigned build, and regenerated
# after signing if signing runs -- signing rewrites the file, so a
# checksum taken before it would be wrong.
- name: checksums
run: |
cd dist
sha256sum * > SHA256SUMS
cat SHA256SUMS
- uses: actions/upload-artifact@v7
with:
name: unsigned
path: dist/
if-no-files-found: error
sign:
needs: build
runs-on: ubuntu-latest
# Inert until the project holds a certificate: set the
# SIGNPATH_ORGANIZATION_ID repository variable to switch this on.
if: vars.SIGNPATH_ORGANIZATION_ID != ''
steps:
- uses: actions/download-artifact@v8
with:
name: unsigned
path: dist
# SignPath's own action pulls the artifact from THIS workflow run by
# its artifact name, submits a signing request, and writes the signed
# result back. Its exact inputs and the action's pinned SHA must be
# taken from SignPath's documentation once the project is accepted --
# I have not run this and will not pretend the argument names below
# are verified. The two that matter and will not change: sign the MSI
# AND the fog-agent.exe inside it (signing only the installer leaves
# the service binary Defender actually watches unsigned), and pin the
# action to a commit SHA rather than a tag.
#
# Deliberately no GitHub Actions expressions in here: an expression is
# expanded into the shell command by the workflow templater, so writing
# a secret into an echo puts it on the command line whether or not the
# shell would have expanded it.
- name: submit signing request
run: |
echo 'Signing is enabled (SIGNPATH_ORGANIZATION_ID is set) but not wired up yet.'
echo 'Replace this step with signpath/github-action-submit-signing-request,'
echo 'pinned to a commit SHA, taking organization-id from the repository'
echo 'variable, project and signing-policy slugs from SignPath, the API'
echo 'token from the SIGNPATH_API_TOKEN secret, and the artifact named'
echo '"unsigned" from this run. Sign the MSI and the fog-agent.exe inside'
echo 'it -- signing only the installer leaves the service binary that'
echo 'Defender actually watches unsigned.'
exit 1 # fail loudly rather than publish unsigned artifacts labelled signed
- name: checksums over the signed files
run: |
cd dist
rm -f SHA256SUMS
sha256sum * > SHA256SUMS
- uses: actions/upload-artifact@v7
with:
name: signed
path: dist/
if-no-files-found: error
publish:
needs: [build, sign]
# sign is skipped, not failed, while the project has no certificate.
if: always() && needs.build.result == 'success' && needs.sign.result != 'failure'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/download-artifact@v8
with:
name: ${{ needs.sign.result == 'success' && 'signed' || 'unsigned' }}
path: dist
# Written to a file rather than passed inline: --notes takes the body
# verbatim, and a body assembled by string-substitution into a shell
# command is one stray quote away from being a different command.
- name: say whether these artifacts are signed
env:
SIGN_RESULT: ${{ needs.sign.result }}
run: |
if [ "$SIGN_RESULT" = "success" ]; then
echo 'Windows artifacts are code-signed.' > notes.md
else
{
echo '**These artifacts are NOT code-signed.** Windows will warn on'
echo 'install and Defender may quarantine the agent. See'
echo 'docs/signing/signpath-application.md for why, and what fixes it.'
} > notes.md
fi
- name: publish the release
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release create "${GITHUB_REF_NAME}" \
--repo "${GITHUB_REPOSITORY}" \
--title "${GITHUB_REF_NAME}" \
--generate-notes \
--notes-file notes.md \
dist/*