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
3128 semanticVersion : ${{ steps.set_version.outputs.semantic_version }}
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
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-dlls
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