Skip to content

Commit 648355b

Browse files
committed
WIP #254 and essentially #364
This introduces some (as yet untested) new pipelines. I'm essentially doing #364 as well as #254 because this also includes refactoring the pipeline into reusable chunks.
1 parent 92bd132 commit 648355b

13 files changed

Lines changed: 389 additions & 258 deletions
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name: 'Restore third-party dependencies'
2+
description: 'Restores dependencies from NuGet and npm'
3+
4+
runs:
5+
using: 'composite'
6+
steps:
7+
- name: Restore .NET packages
8+
run: dotnet restore
9+
- name: Restore Node modules
10+
working-directory: CSF.Screenplay.JsonToHtmlReport.Template/src
11+
run: npm ci
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: 'Run all tests, with coverage'
2+
description: 'Runs all tests for CSF.Screenplay (JS and .NET), with coverage; requires that all .NET projects are already built'
3+
inputs:
4+
configuration:
5+
description: 'The .NET configuration'
6+
default: 'Debug'
7+
tfm:
8+
description: 'The .NET Target Framework Moniker'
9+
required: true
10+
test-results-path:
11+
description: 'The path at which to save test results'
12+
default: 'TestResults'
13+
outputs:
14+
failures:
15+
description: 'Gets a value: `true` or `false` indicating whether or not the tests failed'
16+
value: ${{ steps.emit_output.failures }}
17+
18+
runs:
19+
using: 'composite'
20+
steps:
21+
- name: Run .NET tests with coverage
22+
env:
23+
Configuration: ${{ inputs.configuration }}
24+
Tfm: ${{ inputs.tfm }}
25+
id: dotnet_tests
26+
shell: bash {0}
27+
run: |
28+
for proj in Tests/*.Tests
29+
do
30+
projNameArray=(${proj//// })
31+
projName=${projNameArray[1]}
32+
assemblyPath=$proj/bin/$Configuration/$Tfm/$projName.dll
33+
coverlet "$assemblyPath" --target "dotnet" --targetargs "test $proj -c $Configuration --no-build --logger:nunit --test-adapter-path:." -f=opencover -o="${{ inputs.test-results-path }}/$projName.opencover.xml"
34+
exitCode=$?
35+
if [ $exitCode -ne 0 ]
36+
then
37+
echo "One or more tests have failed; this build should eventually fail"
38+
echo "failures=true" >> "$GITHUB_OUTPUT"
39+
fi
40+
done
41+
- name: Run Client script tests with coverage
42+
id: js_tests
43+
shell: bash {0}
44+
working-directory: CSF.Screenplay.JsonToHtmlReport.Template/src
45+
run: |
46+
npm test
47+
exitCode=$?
48+
if [ $exitCode -ne 0 ]
49+
then
50+
echo "One or more tests have failed; this build should eventually fail"
51+
echo "failures=true" >> "$GITHUB_OUTPUT"
52+
fi
53+
- name: Emit output
54+
id: emit_output
55+
run: |
56+
if [ ${{ steps.dotnet_tests.outputs.failures }} -eq 'true' -o ${{ steps.js_tests.outputs.failures }} -eq 'true' ]
57+
then
58+
echo "failures=true" >> "$GITHUB_OUTPUT"
59+
else
60+
echo "failures=false" >> "$GITHUB_OUTPUT"
61+
fi
62+
shell: bash
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: 'Setup build dependencies'
2+
description: 'Installs and configures mandatory dependencies to build CSF.Screenplay'
3+
inputs:
4+
dotnet-version:
5+
description: 'The version of the .NET SDK to install'
6+
default: '8.0.x'
7+
8+
runs:
9+
using: 'composite'
10+
steps:
11+
- name: Add .NET global tools location to PATH
12+
run: echo "$HOME/.dotnet/tools" >> "$GITHUB_PATH"
13+
- name: Install .NET
14+
uses: actions/setup-dotnet@v5
15+
with:
16+
dotnet-version: ${{ inputs.dotnet-version }}
17+
- name: Install DocFX
18+
run: dotnet tool install --global docfx
19+
- name: Install Node.js for building JSON-to-HTML report converter
20+
uses: actions/setup-node@v6.2.0
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: 'Setup test dependencies'
2+
description: 'Installs and configures additional dependencies to thoroughly test CSF.Screenplay'
3+
inputs:
4+
java-version:
5+
description: 'The version of Java to install'
6+
default: 21
7+
java-dist:
8+
description: 'The distribution of Java to install'
9+
default: 'zulu'
10+
x-display:
11+
description: 'The XServer display to configure for web browsers'
12+
default: ':99'
13+
x-resolution:
14+
description: 'The XServer screen resolution `widthxheight` for web browsers'
15+
default: '1280x1024'
16+
17+
runs:
18+
using: 'composite'
19+
steps:
20+
# Installation
21+
- name: Install SonarScanner
22+
run: dotnet tool install --global dotnet-sonarscanner
23+
- name: Install Coverlet console
24+
run: dotnet tool install --global coverlet.console
25+
- name: Install Java JDK for SonarScanner
26+
uses: actions/setup-java@v5.1.0
27+
with:
28+
java-version: ${{ inputs.java-version }}
29+
distribution: ${{ inputs.java-dist }}
30+
31+
# Prepare to run Chrome
32+
# See https://chromium.googlesource.com/chromium/src/+/main/docs/security/apparmor-userns-restrictions.md
33+
- name: Disable AppArmor restrictions so Chrome may run
34+
run: echo 0 | sudo tee /proc/sys/kernel/apparmor_restrict_unprivileged_userns
35+
- name: Start an Xvfb display so Chrome may run
36+
run: Xvfb -ac ${{ inputs.x-display }} -screen 0 ${{ inputs.x-resolution }}x16 &
37+
38+
# Prime Selenium manager with initial config
39+
- name: Setup Selenium Manager config
40+
run: |
41+
mkdir ~/.cache/selenium
42+
cp Tools/se-config.toml ~/.cache/selenium
43+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: 'Checkout CSF.Screenplay'
2+
description: 'Checks out the repository using standard options'
3+
inputs:
4+
fetch-depth:
5+
description: 'The checkout fetch depth'
6+
default: 0
7+
8+
runs:
9+
using: 'composite'
10+
steps:
11+
- name: Checkout
12+
uses: actions/checkout@v6
13+
with:
14+
fetch-depth: ${{ inputs.fetch-depth }}
15+
lfs: true
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: 'Start SonarScanner'
2+
description: 'Starts up SonarScanner, to analyse a build & test run'
3+
inputs:
4+
project:
5+
description: 'The SonarQube project name'
6+
required: true
7+
build-version:
8+
description: 'The build version string to pass to SonarQube'
9+
required: true
10+
username:
11+
description: 'The SonarQube login username'
12+
required: true
13+
secret-key:
14+
description: 'The SonarQube secret key'
15+
required: true
16+
sonar-cloud-url:
17+
description: 'The SonarCloud URL'
18+
default: 'https://sonarcloud.io'
19+
js-coverage-path:
20+
description: 'The file system path at which to find the JS lcov report'
21+
required: true
22+
analysis-properties-path:
23+
description: 'The file system path at which to find the SonarQube analysis properties file'
24+
default: '.sonarqube-analysisproperties.xml'
25+
26+
27+
runs:
28+
using: 'composite'
29+
steps:
30+
- name: Start SonarScanner
31+
env:
32+
BranchName: ${{ github.event_name == 'pull_request' && github.base_ref || github.ref_name }}
33+
BranchParam: ${{ github.event_name == 'pull_request' && 'sonar.pullrequest.branch' || 'sonar.branch.name' }}
34+
PullRequestParam: ${{ github.event_name == 'pull_request' && format('/d:sonar.pullrequest.key={0}', github.event.number) || '' }}
35+
36+
run: >
37+
dotnet sonarscanner begin
38+
/k:${{ inputs.project }}
39+
/v:${{ inputs.build-version }}
40+
/o:${{ inputs.username }}
41+
/d:sonar.host.url=${{ inputs.sonar-cloud-url }}
42+
/d:sonar.token=${{ inputs.secret-key }}
43+
/d:${{ env.BranchParam }}=${{ env.BranchName }} ${{ env.PullRequestParam }}
44+
/d:sonar.javascript.lcov.reportPaths=$PWD/${{ inputs.js-coverage-path }}
45+
/s:$PWD/${{ inputs.analysis-properties-path }}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: 'Upload CI artifacts'
2+
description: 'Uploads artifacts from a CI run (full build and test), following a full test run'
3+
inputs:
4+
configuration:
5+
description: 'The .NET configuration'
6+
default: 'Debug'
7+
tfm:
8+
description: 'The .NET Target Framework Moniker'
9+
required: true
10+
11+
runs:
12+
using: 'composite'
13+
steps:
14+
- name: Upload .NET test results artifacts
15+
uses: actions/upload-artifact@v7
16+
with:
17+
name: NUnit test results
18+
path: Tests/*.Tests/**/TestResults.xml
19+
- name: Upload verbose webdriver log artifacts
20+
# This step is only relevant if the ChromeDriver with verbose logging is selected, such as via
21+
# appsettings.json in CSF.Screenplay.Selenium.Tests.
22+
# If verbose logs aren't created then this step is skipped to avoid a build warning about missing artifacts.
23+
if: ${{ hashFiles('**/chrome-verbose-log.txt') != '' }}
24+
uses: actions/upload-artifact@v7
25+
with:
26+
name: Verbose webdriver logs
27+
path: '**/chrome-verbose-log.txt'
28+
- name: Upload JS test results artifacts
29+
uses: actions/upload-artifact@v7
30+
with:
31+
name: Client script test results
32+
path: CSF.Screenplay.JsonToHtmlReport.Template/src/TestResults/**/*
33+
- name: Upload Screenplay JSON report artifact
34+
uses: actions/upload-artifact@v7
35+
with:
36+
name: Screenplay JSON reports
37+
path: Tests/**/ScreenplayReport.json
38+
- name: Convert Screenplay reports to HTML
39+
continue-on-error: true
40+
run: |
41+
for report in $(find Tests/ -type f -name "ScreenplayReport.json")
42+
do
43+
reportDir=$(dirname "$report")
44+
outputFile="$reportDir/ScreenplayReport.html"
45+
dotnet run --no-build --framework ${{ inputs.tfm }} -c ${{ inputs.configuration }} --project CSF.Screenplay.JsonToHtmlReport --ReportPath "$report" --OutputPath "$outputFile"
46+
done
47+
- name: Upload Screenplay HTML report artifact
48+
uses: actions/upload-artifact@v7
49+
with:
50+
name: Screenplay HTML reports
51+
path: Tests/**/ScreenplayReport.html

.github/workflows/crossBrowserTesting.yml

Lines changed: 8 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ concurrency:
55
cancel-in-progress: false
66

77
on:
8-
push:
9-
branches: [ "master" ]
10-
pull_request:
11-
branches: [ "master" ]
8+
workflow_run:
9+
workflows: [.NET CI]
10+
types: [completed]
11+
branches: [master]
1212
schedule:
1313
- cron: "27 20 * * 0"
1414

@@ -61,6 +61,7 @@ jobs:
6161
name: Run tests
6262
runs-on: ubuntu-24.04
6363
timeout-minutes: 30
64+
if: ${{ github.event_name == 'schedule' || github.event.workflow_run.conclusion == 'success' }}
6465

6566
env:
6667
RunNumber: ${{ github.run_number }}.${{ github.run_attempt }}
@@ -80,29 +81,9 @@ jobs:
8081
BSparallelism: 5
8182

8283
steps:
83-
- name: Checkout
84-
uses: actions/checkout@v6
85-
86-
# Install build dependencies
87-
88-
- name: Install .NET
89-
uses: actions/setup-dotnet@v5
90-
with:
91-
dotnet-version: ${{ env.DotnetVersion }}
92-
- name: Install Node.js for building JSON-to-HTML report converter
93-
uses: actions/setup-node@v6.2.0
94-
95-
# Environment setup pre-build
96-
97-
- name: Restore .NET packages
98-
run: dotnet restore
99-
- name: Restore Node modules
100-
run: |
101-
cd CSF.Screenplay.JsonToHtmlReport.Template/src
102-
npm ci
103-
cd ../..
104-
105-
# Build and test the solution
84+
- uses: ./.github/actions/standard-checkout
85+
- uses: ./.github/actions/setup-build-dependencies
86+
- uses: ./.github/actions/restore-dependencies
10687

10788
- name: Build the solution
10889
run: dotnet build -c ${{ env.Configuration }}

0 commit comments

Comments
 (0)