Skip to content

Commit 60bcddf

Browse files
ci: lots of updates to how we're releasing
1 parent eced9ed commit 60bcddf

File tree

1 file changed

+81
-64
lines changed

1 file changed

+81
-64
lines changed

.github/workflows/csharp_release.yml

Lines changed: 81 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,23 @@ jobs:
99
name: Set Variables
1010
runs-on: ubuntu-latest
1111
env:
12-
# ⚠️ IMPORTANT: tag should always start with integer & will be used verbatim to string end
1312
TAG: ${{ github.event.release.tag_name }}
1413
steps:
15-
- name: Set semantic version variable
14+
- name: Extract semantic version from tag
1615
id: set_version
1716
run: |
18-
SEMANTIC_VERSION=$(echo "$TAG" | grep -Po "(?<=^|[^0-9])([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?(-[a-zA-Z]+[0-9]*)?)")
17+
# Remove the "v" prefix if it exists and extract the semantic version number
18+
SEMANTIC_VERSION=$(echo "${TAG}" | grep -Po "(?<=^|[^0-9])([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?(-[a-zA-Z]+[0-9]*)?)")
19+
SEMANTIC_VERSION=${SEMANTIC_VERSION#"v"}
1920
if [ -z "${SEMANTIC_VERSION}" ]; then
20-
echo "Tag did not start with a semantic version number (e.g., #.#.#; #.#.#.#; #.#.#.#-beta)"
21+
echo "Error: Tag '${TAG}' does not start with a valid semantic version number (e.g., #.#.#; #.#.#.#; #.#.#.#-beta)"
2122
exit 1
2223
fi
24+
echo "Extracted semantic version: ${SEMANTIC_VERSION}"
2325
echo "semantic_version=${SEMANTIC_VERSION}" >> $GITHUB_OUTPUT
24-
- name: Output tag & semantic version
25-
id: outputs
26-
run: |
27-
echo "$TAG"
28-
echo ${{ steps.set_version.outputs.semantic_version }}
2926
outputs:
3027
tag: $TAG
31-
semanticVersion: ${{ steps.set_version.outputs.semantic_version }}
28+
semanticVersion: ${{ steps.set_version.outputs.semantic_version }}
3229

3330
buildFrameworkVersions:
3431
name: Build Framework versions
@@ -48,9 +45,9 @@ jobs:
4845
- name: Build and strongly name assemblies
4946
run: msbuild /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=$(pwd)/keypair.snk /p:Configuration=Release ./OptimizelySDK.NETFramework.sln
5047
- name: Upload Framework artifacts
51-
uses: actions/upload-artifact@v2
48+
uses: actions/upload-artifact@v4
5249
with:
53-
name: nuget-files
50+
name: unsigned-dlls
5451
if-no-files-found: error
5552
path: ./**/bin/Release/**/Optimizely*.dll
5653

@@ -70,9 +67,9 @@ jobs:
7067
- name: Build and strongly name assemblies
7168
run: dotnet build OptimizelySDK.NetStandard16/OptimizelySDK.NetStandard16.csproj /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=$(pwd)/keypair.snk -c Release
7269
- name: Upload Standard 1.6 artifact
73-
uses: actions/upload-artifact@v2
70+
uses: actions/upload-artifact@v4
7471
with:
75-
name: nuget-files
72+
name: unsigned-dlls
7673
if-no-files-found: error
7774
path: ./**/bin/Release/**/Optimizely*.dll
7875

@@ -92,77 +89,95 @@ jobs:
9289
- name: Build and strongly name Standard 2.0 project
9390
run: dotnet build OptimizelySDK.NetStandard20/OptimizelySDK.NetStandard20.csproj /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=$(pwd)/keypair.snk -c Release
9491
- name: Build and strongly name assemblies
95-
uses: actions/upload-artifact@v2
92+
uses: actions/upload-artifact@v4
9693
with:
97-
name: nuget-files
94+
name: unsigned-dlls
9895
if-no-files-found: error
9996
path: ./**/bin/Release/**/Optimizely*.dll
10097

101-
pack:
102-
name: Sign & pack NuGet package
98+
sign:
99+
name: Send DLLs for signing
103100
needs: [ variables, buildFrameworkVersions, buildStandard16, buildStandard20 ]
104101
runs-on: ubuntu-latest
102+
env:
103+
# TODO: Replace actual values
104+
SIGNING_SERVER_PRIVATE_KEY: ${{ secrets.SIGNING_SERVER_PRIVATE_KEY }}
105+
SIGNING_SERVER_HOST: ${{ secrets.SIGNING_SERVER_HOST }}
106+
SIGNING_SERVER_UPLOAD_PATH: /path/to/UPLOAD/directory
107+
SIGNING_SERVER_DOWNLOAD_PATH: /path/to/DOWNLOAD/directory
108+
steps:
109+
# TODO: Remove this when we're ready to automate
110+
- name: Temporarily halt progress
111+
run: exit 1
112+
- name: Download the unsigned files
113+
uses: actions/download-artifact@v4
114+
with:
115+
name: unsigned-dlls
116+
path: ./unsigned-dlls
117+
- name: Setup SSH
118+
uses: shimataro/ssh-key-action@v2
119+
with:
120+
key: $SIGNING_SERVER_PRIVATE_KEY
121+
- name: Send files to signing server
122+
run: scp -r ./unsigned-dlls $SIGNING_SERVER_HOST:$SIGNING_SERVER_UPLOAD_PATH
123+
- name: Wait for artifact to be published
124+
run: |
125+
for i in {1..60}; do
126+
# Replace with actual path
127+
if ssh $SIGNING_SERVER_HOST "ls $SIGNING_SERVER_DOWNLOAD_PATH"; then
128+
exit 0
129+
fi
130+
sleep 10
131+
done
132+
exit 1
133+
- name: Download signed files
134+
run: |
135+
mkdir ./signed-dlls
136+
scp -r $SIGNING_SERVER_HOST:$SIGNING_SERVER_DOWNLOAD_PATH ./signed-dlls
137+
- name: Delete signed files from server
138+
run: ssh $SIGNING_SERVER_HOST "rm -rf $SIGNING_SERVER_DOWNLOAD_PATH/*"
139+
- name: Upload signed files
140+
uses: actions/upload-artifact@v4
141+
with:
142+
name: signed-dlls
143+
if-no-files-found: error
144+
path: ./signed-dlls
145+
146+
pack:
147+
name: Pack NuGet package
148+
needs: [ variables, sign ]
149+
runs-on: ubuntu-latest
105150
env:
106151
VERSION: ${{ needs.variables.outputs.semanticVersion }}
107152
steps:
108153
- name: Checkout code
109-
uses: actions/checkout@v3
154+
uses: actions/checkout@v4
110155
with:
111156
ref: ${{ needs.variables.outputs.tag }}
112157
- name: Install mono
113158
run: |
114159
sudo apt update
115160
sudo apt install -y mono-devel
116161
- name: Download NuGet files
117-
uses: actions/download-artifact@v2
162+
uses: actions/download-artifact@v4
118163
with:
119-
name: nuget-files
120-
path: ./nuget-files
164+
name: signed-dlls
165+
path: ./signed-dlls
121166
- name: Organize files
122167
run: |
123-
pushd ./nuget-files
168+
pushd ./signed-files
124169
# Move all dlls to the root directory
125-
find . -type f -name "*.dll" -exec mv {} . \;
170+
find . -type f -name "*.dll" -exec mv {} .
126171
popd
127172
# Create directories
128173
mkdir -p nuget/lib/net35/ nuget/lib/net40/ nuget/lib/net45/ nuget/lib/netstandard1.6/ nuget/lib/netstandard2.0/
129174
pushd ./nuget
130175
# Move files to directories
131-
mv ../nuget-files/OptimizelySDK.Net35.dll lib/net35/
132-
mv ../nuget-files/OptimizelySDK.Net40.dll lib/net40/
133-
mv ../nuget-files/OptimizelySDK.dll lib/net45/
134-
mv ../nuget-files/OptimizelySDK.NetStandard16.dll lib/netstandard1.6/
135-
mv ../nuget-files/OptimizelySDK.NetStandard20.dll lib/netstandard2.0/
136-
popd
137-
- name: Setup signing prerequisites
138-
env:
139-
CERTIFICATE_P12: ${{ secrets.CERTIFICATE_P12 }}
140-
CERTIFICATE_PASSWORD: ${{ secrets.CERTIFICATE_PASSWORD }}
141-
run: |
142-
pushd ./nuget
143-
echo $CERTIFICATE_P12 | base64 --decode > authenticode.pfx
144-
openssl pkcs12 -in authenticode.pfx -nocerts -nodes -legacy -out key.pem -password env:CERTIFICATE_PASSWORD
145-
openssl rsa -in key.pem -outform PVK -pvk-none -out authenticode.pvk
146-
openssl pkcs12 -in authenticode.pfx -nokeys -nodes -legacy -out cert.pem -password env:CERTIFICATE_PASSWORD
147-
openssl crl2pkcs7 -nocrl -certfile cert.pem -outform DER -out authenticode.spc
148-
popd
149-
- name: Sign the DLLs
150-
run: |
151-
pushd ./nuget
152-
find . -type f -name "*.dll" -print0 | while IFS= read -r -d '' file; do
153-
echo "Signing ${file}"
154-
signcode \
155-
-spc ./authenticode.spc \
156-
-v ./authenticode.pvk \
157-
-a sha1 -$ commercial \
158-
-n "Optimizely, Inc" \
159-
-i "https://www.optimizely.com/" \
160-
-t "http://timestamp.digicert.com" \
161-
-tr 10 \
162-
${file}
163-
rm ${file}.bak
164-
done
165-
rm *.spc *.pem *.pvk *.pfx
176+
mv ../signed-dlls/OptimizelySDK.Net35.dll lib/net35/
177+
mv ../signed-dlls/OptimizelySDK.Net40.dll lib/net40/
178+
mv ../signed-dlls/OptimizelySDK.dll lib/net45/
179+
mv ../signed-dlls/OptimizelySDK.NetStandard16.dll lib/netstandard1.6/
180+
mv ../signed-dlls/OptimizelySDK.NetStandard20.dll lib/netstandard2.0/
166181
popd
167182
- name: Create nuspec
168183
# Uses env.VERSION in OptimizelySDK.nuspec.template
@@ -175,27 +190,29 @@ jobs:
175190
nuget pack OptimizelySDK.nuspec
176191
popd
177192
- name: Upload nupkg artifact
178-
uses: actions/upload-artifact@v2
193+
uses: actions/upload-artifact@v4
179194
with:
180195
name: nuget-package
181196
if-no-files-found: error
182197
path: ./nuget/Optimizely.SDK.${{ env.VERSION }}.nupkg
183198

184199
publish:
185-
name: Publish package to NuGet
200+
name: Publish package to NuGet after reviewing the artifact
186201
needs: [ variables, pack ]
187202
runs-on: ubuntu-latest
203+
# Review the `nuget-package` artifact ensuring the dlls are
204+
# organized and signed before approving.
205+
environment: 'i-reviewed-nuget-package-artifact'
188206
env:
189207
VERSION: ${{ needs.variables.outputs.semanticVersion }}
190208
steps:
191209
- name: Download NuGet files
192-
uses: actions/download-artifact@v2
210+
uses: actions/download-artifact@v4
193211
with:
194212
name: nuget-package
195213
path: ./nuget
196214
- name: Setup .NET
197-
uses: actions/setup-dotnet@v3
215+
uses: actions/setup-dotnet@v4
198216
- name: Publish NuGet package
199-
# Unset secrets.NUGET_API_KEY to simulate dry run
200217
run: |
201218
dotnet nuget push ./nuget/Optimizely.SDK.${{ env.VERSION }}.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_KEY }}

0 commit comments

Comments
 (0)