Skip to content

Commit b658323

Browse files
[FSSDK-9486] maint: Update CI and publishing (#356)
* Add remote dispatch workflow * Update job & step names * Stop uploading to AWS * Reorganized jobs * Change workflow names * Fix on.push.branches for testing * Rename job * Rename steps; remove second strong name signing for .NET Framework assems * Combine two steps * Run tests before release build * NIT changes * Move NUnit tests after build * Remove testing branch push trigger * Renamings; remove test trigger * Rename jobs for consistency * Revert "Rename jobs for consistency" This reverts commit c159538. * Update from @jaeopt PR review * Add back CI_USER_TOKEN secret * Add back TRAVIS_COM_TOKEN * Update release workflow for testing * Fix test tag * Testing fix use OptimizelySDK.Travis.sln since I'm testing using previous release * Adjust names * Migrate nuspec template * Fix checkout during pack; output tag & version * Fix output of env.TAG * Shorten & fix during testing * Add back jobs * Update OptimizelySDK.nuspec.template's permission * Iterate on nuspec creation * Fix semantic extraction * Fix dotnet nuget push * Move env to steps where they're needed * Remove testing setups
1 parent 471ca4b commit b658323

File tree

7 files changed

+253
-201
lines changed

7 files changed

+253
-201
lines changed

.github/workflows/csharp.yml

+39-73
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
1-
---
2-
name: Csharp CI with .NET
1+
name: Continuous Integration
32

43
on:
54
push:
6-
branches: [master]
5+
branches: [ master ]
76
pull_request:
8-
branches: [master]
9-
10-
env:
11-
RELEASE_BRANCH: "master"
12-
WINDOWS_2019_SN_PATH: C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\sn.exe
7+
branches: [ master ]
138

149
jobs:
15-
lint_code_base:
10+
lintCodebase:
1611
runs-on: ubuntu-latest
1712
name: Lint Codebase
1813
steps:
@@ -21,32 +16,17 @@ jobs:
2116
with:
2217
# Full git history is needed to get a proper list of changed files
2318
fetch-depth: 0
24-
- name: Lint codebase
19+
- name: Run Super-Linter
2520
uses: github/super-linter@v4
2621
env:
2722
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2823
VALIDATE_ALL_CODEBASE: false
2924
DEFAULT_BRANCH: master
3025
VALIDATE_CSHARP: true
31-
32-
integration_tests:
33-
name: Run Integration Tests
34-
uses: optimizely/csharp-sdk/.github/workflows/integration_test.yml@master
35-
secrets:
36-
CI_USER_TOKEN: ${{ secrets.CI_USER_TOKEN }}
37-
TRAVIS_COM_TOKEN: ${{ secrets.TRAVIS_COM_TOKEN }}
38-
39-
fullstack_production_suite:
40-
name: Run Optimizely Feature Experimentation Compatibility Suite
41-
uses: optimizely/csharp-sdk/.github/workflows/integration_test.yml@master
42-
with:
43-
FULLSTACK_TEST_REPO: ProdTesting
44-
secrets:
45-
CI_USER_TOKEN: ${{ secrets.CI_USER_TOKEN }}
46-
TRAVIS_COM_TOKEN: ${{ secrets.TRAVIS_COM_TOKEN }}
4726

48-
unit_test:
49-
name: Build and Run Unit Tests
27+
netFrameworksAndUnitTest:
28+
name: Build Framework & Run Unit Tests
29+
needs: [ lintCodebase ]
5030
runs-on: windows-2019 # required version for Framework 4.0
5131
env:
5232
REPO_SLUG: ${{ github.repository }}
@@ -63,33 +43,18 @@ jobs:
6343
- name: Setup NuGet
6444
uses: NuGet/setup-nuget@v1
6545
- name: Restore NuGet packages
66-
run: nuget restore ./OptimizelySDK.Travis.sln
67-
- name: Build solution
68-
run: msbuild /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=$(pwd)/keypair.snk /p:Configuration=Release ./OptimizelySDK.Travis.sln
69-
- name: Install NUnit Console
70-
run: nuget install NUnit.Console -Version 3.15.2 -DirectDownload -OutputDirectory .
71-
- name: Run NUnit tests
72-
# https://docs.nunit.org/articles/nunit/running-tests/Console-Command-Line.html
73-
run: ./NUnit.ConsoleRunner.3.15.2\tools\nunit3-console.exe /timeout 10000 /process Separate ./OptimizelySDK.Tests/bin/Release/OptimizelySDK.Tests.dll
74-
- name: Find and sign all DLLs
75-
id: unit_tests
76-
run: |
77-
Get-ChildItem -Recurse -Exclude '.*Tests.*' -Include 'OptimizelySDK*.dll' |
78-
Where-Object { $_.DirectoryName -match '\\bin\\Release' } |
79-
Foreach-Object { & $env:WINDOWS_2019_SN_PATH -R $_.FullName ./keypair.snk }
80-
- name: Install AWS CLI, deploy to S3 on successful tests & for release
81-
if: steps.unit_tests.outcome == 'success' && env.CURRENT_BRANCH == env.RELEASE_BRANCH && env.EVENT_TYPE == 'push'
82-
env:
83-
AWS_ACCESS_KEY_ID: ${{ secrets.OFTA_KEY }}
84-
AWS_SECRET_ACCESS_KEY: ${{ secrets.OFTA_SECRET }}
85-
AWS_DEFAULT_REGION: ${{ secrets.OFTA_REGION }}
46+
run: nuget restore ./OptimizelySDK.NETFramework.sln
47+
- name: Build & strongly name assemblies
48+
run: msbuild /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=$(pwd)/keypair.snk /p:Configuration=Release ./OptimizelySDK.NETFramework.sln
49+
- name: Install & Run NUnit tests
8650
run: |
87-
Install-Module -Name AWS.Tools.Installer -Force;
88-
Install-AWSToolsModule AWS.Tools.S3 -Force -CleanUp;
89-
Get-ChildItem -Recurse -Exclude '.*Tests.*' -include 'OptimizelySDK*.dll' | Where-Object { $_.DirectoryName -match '\\bin\\Release' } | Foreach-Object { aws s3 cp $_.FullName s3://optly-fs-travisci-artifacts/${{ env.REPO_SLUG }}/${{ env.BUILD_NUMBER }}/${{ env.RUN_NUMBER }}/${{ env.ATTEMPT_NUM }}/$($_.Name)-unsigned }
51+
nuget install NUnit.Console -Version 3.15.2 -DirectDownload -OutputDirectory .
52+
# https://docs.nunit.org/articles/nunit/running-tests/Console-Command-Line.html
53+
./NUnit.ConsoleRunner.3.15.2\tools\nunit3-console.exe /timeout 10000 /process Separate ./OptimizelySDK.Tests/bin/Release/OptimizelySDK.Tests.dll
9054
9155
netStandard16:
92-
name: Build For .NET Standard 1.6
56+
name: Build Standard 1.6
57+
needs: [ netFrameworksAndUnitTest ]
9358
runs-on: windows-2022
9459
env:
9560
REPO_SLUG: ${{ github.repository }}
@@ -107,20 +72,12 @@ jobs:
10772
dotnet-version: 3.1.x
10873
- name: Restore dependencies
10974
run: dotnet restore OptimizelySDK.NetStandard16/OptimizelySDK.NetStandard16.csproj
110-
- name: Build and sign Standard 1.6 project
111-
id: netStandard16_build
75+
- name: Build & strongly name assemblies
11276
run: dotnet build OptimizelySDK.NetStandard16/OptimizelySDK.NetStandard16.csproj /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=D:\a\csharp-sdk\csharp-sdk\keypair.snk -c Release
113-
- name: Check on success
114-
if: steps.netStandard16_build.outcome == 'success' && env.CURRENT_BRANCH == env.RELEASE_BRANCH && env.EVENT_TYPE == 'push'
115-
env:
116-
AWS_ACCESS_KEY_ID: ${{ secrets.OFTA_KEY }}
117-
AWS_SECRET_ACCESS_KEY: ${{ secrets.OFTA_SECRET }}
118-
AWS_DEFAULT_REGION: ${{ secrets.OFTA_REGION }}
119-
run: |
120-
(aws s3 cp ./OptimizelySDK.NetStandard16/bin/Release/netstandard1.6/OptimizelySDK.NetStandard16.dll s3://optly-fs-travisci-artifacts/${{ env.REPO_SLUG }}/${{ env.BUILD_NUMBER }}/${{ env.RUN_NUMBER }}/${{ env.ATTEMPT_NUM }}/OptimizelySDK.NetStandard16.dll-unsigned)
12177

12278
netStandard20:
123-
name: Build For .NET Standard 2.0
79+
name: Build Standard 2.0
80+
needs: [ netFrameworksAndUnitTest ]
12481
runs-on: windows-2022
12582
env:
12683
REPO_SLUG: ${{ github.repository }}
@@ -138,14 +95,23 @@ jobs:
13895
dotnet-version: 3.1.x
13996
- name: Restore dependencies
14097
run: dotnet restore OptimizelySDK.NetStandard20/OptimizelySDK.NetStandard20.csproj
141-
- name: Build and sign Standard 2.0 project
142-
id: netStandard20_build
98+
- name: Build & strongly name assemblies
14399
run: dotnet build OptimizelySDK.NetStandard20/OptimizelySDK.NetStandard20.csproj /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=D:\a\csharp-sdk\csharp-sdk\keypair.snk -c Release
144-
- name: Check on success
145-
if: steps.netStandard20_build.outcome == 'success' && env.CURRENT_BRANCH == env.RELEASE_BRANCH && env.EVENT_TYPE == 'push'
146-
env:
147-
AWS_ACCESS_KEY_ID: ${{ secrets.OFTA_KEY }}
148-
AWS_SECRET_ACCESS_KEY: ${{ secrets.OFTA_SECRET }}
149-
AWS_DEFAULT_REGION: ${{ secrets.OFTA_REGION }}
150-
run: |
151-
(aws s3 cp ./OptimizelySDK.NetStandard20/bin/Release/netstandard2.0/OptimizelySDK.NetStandard20.dll s3://optly-fs-travisci-artifacts/${{ env.REPO_SLUG }}/${{ env.BUILD_NUMBER }}/${{ env.RUN_NUMBER }}/${{ env.ATTEMPT_NUM }}/OptimizelySDK.NetStandard20.dll-unsigned)
100+
101+
integration_tests:
102+
name: Run Integration Tests
103+
needs: [ netFrameworksAndUnitTest, netStandard16, netStandard20 ]
104+
uses: optimizely/csharp-sdk/.github/workflows/integration_test.yml@master
105+
secrets:
106+
CI_USER_TOKEN: ${{ secrets.CI_USER_TOKEN }}
107+
TRAVIS_COM_TOKEN: ${{ secrets.TRAVIS_COM_TOKEN }}
108+
109+
fullstack_production_suite:
110+
name: Run Performance Tests
111+
needs: [ netFrameworksAndUnitTest, netStandard16, netStandard20 ]
112+
uses: optimizely/csharp-sdk/.github/workflows/integration_test.yml@master
113+
with:
114+
FULLSTACK_TEST_REPO: ProdTesting
115+
secrets:
116+
CI_USER_TOKEN: ${{ secrets.CI_USER_TOKEN }}
117+
TRAVIS_COM_TOKEN: ${{ secrets.TRAVIS_COM_TOKEN }}

.github/workflows/csharp_release.yml

+202
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
name: Publish Release To NuGet
2+
3+
on:
4+
release:
5+
types: [ published ] # Trigger on published pre-releases and releases
6+
7+
jobs:
8+
variables:
9+
name: Set Variables
10+
runs-on: ubuntu-latest
11+
env:
12+
# ⚠️ IMPORTANT: tag should always start with integer & will be used verbatim to string end
13+
TAG: ${{ github.event.release.tag_name }}
14+
steps:
15+
- name: Set semantic version variable
16+
id: set_version
17+
run: |
18+
TAG=${{ env.TAG }}
19+
SEMANTIC_VERSION=$(echo "${TAG}" | grep -Po "(?<=^|[^0-9])([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?(-[a-zA-Z]+[0-9]*)?)")
20+
if [ -z "${SEMANTIC_VERSION}" ]; then
21+
echo "Tag did not start with a semantic version number (e.g., #.#.#; #.#.#.#; #.#.#.#-beta)"
22+
exit 1
23+
fi
24+
echo "semantic_version=${SEMANTIC_VERSION}" >> $GITHUB_OUTPUT
25+
- name: Output tag & semantic version
26+
id: outputs
27+
run: |
28+
echo ${{ env.TAG }}
29+
echo ${{ steps.set_version.outputs.semantic_version }}
30+
outputs:
31+
tag: ${{ env.TAG }}
32+
semanticVersion: ${{ steps.set_version.outputs.semantic_version }}
33+
34+
buildFrameworkVersions:
35+
name: Build Framework versions
36+
needs: [ variables ]
37+
runs-on: windows-2019 # required version for Framework 4.0
38+
steps:
39+
- name: Checkout code
40+
uses: actions/checkout@v3
41+
with:
42+
ref: ${{ needs.variables.outputs.tag }}
43+
- name: Add msbuild to PATH
44+
uses: microsoft/setup-msbuild@v1
45+
- name: Setup NuGet
46+
uses: NuGet/setup-nuget@v1
47+
- name: Restore NuGet packages
48+
run: nuget restore ./OptimizelySDK.NETFramework.sln
49+
- name: Build and strongly name assemblies
50+
run: msbuild /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=$(pwd)/keypair.snk /p:Configuration=Release ./OptimizelySDK.NETFramework.sln
51+
- name: Upload Framework artifacts
52+
uses: actions/upload-artifact@v2
53+
with:
54+
name: nuget-files
55+
if-no-files-found: error
56+
path: ./**/bin/Release/**/Optimizely*.dll
57+
58+
buildStandard16:
59+
name: Build Standard 1.6 version
60+
needs: [ variables ]
61+
runs-on: windows-latest
62+
steps:
63+
- name: Checkout code
64+
uses: actions/checkout@v3
65+
with:
66+
ref: ${{ needs.variables.outputs.tag }}
67+
- name: Setup .NET
68+
uses: actions/setup-dotnet@v2
69+
- name: Restore dependencies
70+
run: dotnet restore OptimizelySDK.NetStandard16/OptimizelySDK.NetStandard16.csproj
71+
- name: Build and strongly name assemblies
72+
run: dotnet build OptimizelySDK.NetStandard16/OptimizelySDK.NetStandard16.csproj /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=$(pwd)/keypair.snk -c Release
73+
- name: Upload Standard 1.6 artifact
74+
uses: actions/upload-artifact@v2
75+
with:
76+
name: nuget-files
77+
if-no-files-found: error
78+
path: ./**/bin/Release/**/Optimizely*.dll
79+
80+
buildStandard20:
81+
name: Build Standard 2.0 version
82+
needs: [ variables ]
83+
runs-on: windows-latest
84+
steps:
85+
- name: Checkout code
86+
uses: actions/checkout@v3
87+
with:
88+
ref: ${{ needs.variables.outputs.tag }}
89+
- name: Setup .NET
90+
uses: actions/setup-dotnet@v2
91+
- name: Restore dependencies
92+
run: dotnet restore OptimizelySDK.NetStandard20/OptimizelySDK.NetStandard20.csproj
93+
- name: Build and strongly name Standard 2.0 project
94+
run: dotnet build OptimizelySDK.NetStandard20/OptimizelySDK.NetStandard20.csproj /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=$(pwd)/keypair.snk -c Release
95+
- name: Build and strongly name assemblies
96+
uses: actions/upload-artifact@v2
97+
with:
98+
name: nuget-files
99+
if-no-files-found: error
100+
path: ./**/bin/Release/**/Optimizely*.dll
101+
102+
pack:
103+
name: Sign & pack NuGet package
104+
needs: [ variables, buildFrameworkVersions, buildStandard16, buildStandard20 ]
105+
runs-on: ubuntu-latest
106+
env:
107+
VERSION: ${{ needs.variables.outputs.semanticVersion }}
108+
steps:
109+
- name: Checkout code
110+
uses: actions/checkout@v3
111+
with:
112+
ref: ${{ needs.variables.outputs.tag }}
113+
- name: Install mono
114+
run: |
115+
sudo apt update
116+
sudo apt install -y mono-devel
117+
- name: Download NuGet files
118+
uses: actions/download-artifact@v2
119+
with:
120+
name: nuget-files
121+
path: ./nuget-files
122+
- name: Organize files
123+
run: |
124+
pushd ./nuget-files
125+
# Move all dlls to the root directory
126+
find . -type f -name "*.dll" -exec mv {} . \;
127+
popd
128+
# Create directories
129+
mkdir -p nuget/lib/net35/ nuget/lib/net40/ nuget/lib/net45/ nuget/lib/netstandard1.6/ nuget/lib/netstandard2.0/
130+
pushd ./nuget
131+
# Move files to directories
132+
mv ../nuget-files/OptimizelySDK.Net35.dll lib/net35/
133+
mv ../nuget-files/OptimizelySDK.Net40.dll lib/net40/
134+
mv ../nuget-files/OptimizelySDK.dll lib/net45/
135+
mv ../nuget-files/OptimizelySDK.NetStandard16.dll lib/netstandard1.6/
136+
mv ../nuget-files/OptimizelySDK.NetStandard20.dll lib/netstandard2.0/
137+
popd
138+
- name: Setup signing prerequisites
139+
env:
140+
CERTIFICATE_P12: ${{ secrets.CERTIFICATE_P12 }}
141+
CERTIFICATE_PASSWORD: ${{ secrets.CERTIFICATE_PASSWORD }}
142+
run: |
143+
pushd ./nuget
144+
echo $CERTIFICATE_P12 | base64 --decode > authenticode.pfx
145+
openssl pkcs12 -in authenticode.pfx -nocerts -nodes -legacy -out key.pem -password env:CERTIFICATE_PASSWORD
146+
openssl rsa -in key.pem -outform PVK -pvk-none -out authenticode.pvk
147+
openssl pkcs12 -in authenticode.pfx -nokeys -nodes -legacy -out cert.pem -password env:CERTIFICATE_PASSWORD
148+
openssl crl2pkcs7 -nocrl -certfile cert.pem -outform DER -out authenticode.spc
149+
popd
150+
- name: Sign the DLLs
151+
run: |
152+
pushd ./nuget
153+
find . -type f -name "*.dll" -print0 | while IFS= read -r -d '' file; do
154+
echo "Signing ${file}"
155+
signcode \
156+
-spc ./authenticode.spc \
157+
-v ./authenticode.pvk \
158+
-a sha1 -$ commercial \
159+
-n "Optimizely, Inc" \
160+
-i "https://www.optimizely.com/" \
161+
-t "http://timestamp.digicert.com" \
162+
-tr 10 \
163+
${file}
164+
rm ${file}.bak
165+
done
166+
rm *.spc *.pem *.pvk *.pfx
167+
popd
168+
- name: Create nuspec
169+
# Uses env.VERSION in OptimizelySDK.nuspec.template
170+
run: |
171+
chmod +x ./OptimizelySDK.nuspec.template
172+
./OptimizelySDK.nuspec.template
173+
- name: Pack NuGet package
174+
run: |
175+
pushd ./nuget
176+
nuget pack OptimizelySDK.nuspec
177+
popd
178+
- name: Upload nupkg artifact
179+
uses: actions/upload-artifact@v2
180+
with:
181+
name: nuget-package
182+
if-no-files-found: error
183+
path: ./nuget/Optimizely.SDK.${{ env.VERSION }}.nupkg
184+
185+
publish:
186+
name: Publish package to NuGet
187+
needs: [ variables, pack ]
188+
runs-on: ubuntu-latest
189+
env:
190+
VERSION: ${{ needs.variables.outputs.semanticVersion }}
191+
steps:
192+
- name: Download NuGet files
193+
uses: actions/download-artifact@v2
194+
with:
195+
name: nuget-package
196+
path: ./nuget
197+
- name: Setup .NET
198+
uses: actions/setup-dotnet@v3
199+
- name: Publish NuGet package
200+
# Unset secrets.NUGET_API_KEY to simulate dry run
201+
run: |
202+
dotnet nuget push ./nuget/Optimizely.SDK.${{ env.VERSION }}.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_KEY }}
File renamed without changes.

0 commit comments

Comments
 (0)