Skip to content

Commit f2b1873

Browse files
authored
Merge ea785dc into 7a42d8e
2 parents 7a42d8e + ea785dc commit f2b1873

File tree

18 files changed

+518
-29
lines changed

18 files changed

+518
-29
lines changed
Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
name: Run tests and publish
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
- beta
8+
- rc
9+
- 'try-**'
10+
tags:
11+
- 'release-**'
12+
13+
pull_request:
14+
branches:
15+
- master
16+
- beta
17+
- rc
18+
19+
workflow_dispatch:
20+
21+
concurrency:
22+
group: ${{ github.workflow }}-${{ github.ref }}
23+
cancel-in-progress: true
24+
25+
env:
26+
START_BUILD_NUMBER: 50000
27+
pullRequestNumber: ${{ github.event_name == 'pull_request' && github.event.number || 0 }}
28+
scons_publisher: NV Access
29+
# Comment out any of the feature_* variables to disable the respective build feature.
30+
# They are checked for existence of content, not specific value.
31+
# feature_buildSymbols: configured
32+
# feature_uploadSymbolsToMozilla: configured
33+
# feature_buildAppx: configured
34+
# feature_crowdinSync: configured
35+
# feature_signing: configured
36+
37+
jobs:
38+
buildNVDA:
39+
name: Build NVDA
40+
runs-on: windows-latest
41+
steps:
42+
- name: Checkout NVDA
43+
uses: actions/checkout@v4
44+
with:
45+
submodules: true
46+
- name: Install dependencies
47+
uses: actions/setup-python@v5
48+
with:
49+
python-version: '3.11'
50+
architecture: x86
51+
- name: Set version variables
52+
run: ci/scripts/setBuildVersionVars.ps1
53+
- name: Set scons args
54+
run: ci/scripts/setSconsArgs.ps1
55+
- name: Prepare source code
56+
shell: cmd
57+
run: scons source %sconsArgs% ${{ !runner.debug && '--all-cores' || '-j1' }}
58+
- name: Prepare for tests
59+
run: ci/scripts/tests/beforeTests.ps1
60+
- name: Cache scons build
61+
uses: actions/cache/save@v4
62+
with:
63+
path: ${{ github.workspace }}
64+
key: ${{ github.ref }}-${{ github.run_id }}
65+
66+
checkPot:
67+
name: Check translator comments
68+
runs-on: windows-latest
69+
needs: buildNVDA
70+
steps:
71+
- name: Checkout cached build
72+
uses: actions/cache/restore@v4
73+
with:
74+
path: ${{ github.workspace }}
75+
key: ${{ github.ref }}-${{ github.run_id }}
76+
fail-on-cache-miss: true
77+
- name: Check comments for translators
78+
run: ci/scripts/tests/translationCheck.ps1
79+
- name: Upload artifact
80+
if: ${{ success() || failure() }}
81+
uses: actions/upload-artifact@v4
82+
with:
83+
name: makePot results
84+
path: |
85+
output/nvda.pot
86+
output/potSourceFileList.txt
87+
overwrite: true
88+
89+
licenseCheck:
90+
name: Check license compatibility of dependencies
91+
runs-on: windows-latest
92+
needs: buildNVDA
93+
steps:
94+
- name: Checkout cached build
95+
uses: actions/cache/restore@v4
96+
with:
97+
path: ${{ github.workspace }}
98+
key: ${{ github.ref }}-${{ github.run_id }}
99+
fail-on-cache-miss: true
100+
- name: License check
101+
run: ci/scripts/tests/licenseCheck.ps1
102+
103+
unitTests:
104+
name: Run unit tests
105+
runs-on: windows-latest
106+
needs: buildNVDA
107+
steps:
108+
- name: Checkout cached build
109+
uses: actions/cache/restore@v4
110+
with:
111+
path: ${{ github.workspace }}
112+
key: ${{ github.ref }}-${{ github.run_id }}
113+
fail-on-cache-miss: true
114+
- name: Run unit tests
115+
run: ci/scripts/tests/unitTests.ps1
116+
- name: Replace relative paths in unit test results
117+
if: ${{ success() || failure() }}
118+
# Junit reports fail on these
119+
shell: bash
120+
run: sed -i 's|file="..\\|file="|g' testOutput/unit/unitTests.xml
121+
- name: Upload artifact
122+
if: ${{ success() || failure() }}
123+
uses: actions/upload-artifact@v4
124+
with:
125+
name: Unit tests results
126+
path: testOutput/unit/unitTests.xml
127+
overwrite: true
128+
- name: Publish unit test report
129+
uses: mikepenz/action-junit-report@v5
130+
if: ${{ success() || failure() }}
131+
with:
132+
check_name: Unit tests
133+
detailed_summary: true
134+
annotate_only: true
135+
report_paths: testOutput/unit/unitTests.xml
136+
137+
createLauncher:
138+
name: Create launcher
139+
runs-on: windows-latest
140+
needs: buildNVDA
141+
steps:
142+
- name: Checkout cached build
143+
uses: actions/cache/restore@v4
144+
with:
145+
path: ${{ github.workspace }}
146+
key: ${{ github.ref }}-${{ github.run_id }}
147+
fail-on-cache-miss: true
148+
- name: Set version variables
149+
run: ci/scripts/setBuildVersionVars.ps1
150+
- name: Set scons args
151+
run: ci/scripts/setSconsArgs.ps1
152+
- name: Prepare source code for launcher
153+
shell: cmd
154+
run: scons %sconsOutTargets% %sconsArgs% ${{ !runner.debug && '--all-cores' || '-j1'}}
155+
- name: Build launcher
156+
shell: cmd
157+
run: scons launcher %sconsArgs% ${{ !runner.debug && '--all-cores' || '-j1'}}
158+
- name: Upload launcher
159+
id: uploadLauncher
160+
uses: actions/upload-artifact@v4
161+
with:
162+
name: NVDA launcher
163+
path: output/nvda*.exe
164+
overwrite: true
165+
- name: Upload build artifacts
166+
uses: actions/upload-artifact@v4
167+
id: uploadBuildArtifacts
168+
with:
169+
name: NVDA build artifacts
170+
path: |
171+
output/*
172+
!output/nvda*.exe
173+
!output/nvda.pot
174+
!output/potSourceFileList.txt
175+
overwrite: true
176+
- name: Add job summary
177+
shell: bash
178+
run: |
179+
echo "* [Download the NVDA launcher](${{ steps.uploadLauncher.outputs.artifact-url }}) (${{ steps.uploadLauncher.outputs.artifact-digest }})" >> $GITHUB_STEP_SUMMARY
180+
echo "* [Download the other build artifacts](${{ steps.uploadBuildArtifacts.outputs.artifact-url }})" >> $GITHUB_STEP_SUMMARY
181+
182+
systemTests:
183+
name: Run system tests
184+
runs-on: windows-latest
185+
needs: createLauncher
186+
steps:
187+
- name: Checkout cached build
188+
uses: actions/cache/restore@v4
189+
with:
190+
path: ${{ github.workspace }}
191+
key: ${{ github.ref }}-${{ github.run_id }}
192+
fail-on-cache-miss: true
193+
- name: Get NVDA launcher
194+
id: getLauncher
195+
uses: actions/download-artifact@v4
196+
with:
197+
name: NVDA launcher
198+
path: output
199+
- name: Install NVDA
200+
run: ci/scripts/installNVDA.ps1
201+
env:
202+
nvdaLauncherDir: ${{ steps.getLauncher.outputs.download-path }}
203+
- name: Upload install log
204+
if: ${{ success() || failure() }}
205+
uses: actions/upload-artifact@v4
206+
with:
207+
name: Install log
208+
path: |
209+
testOutput/install
210+
!testOutput/install/nvda_install_temp.log
211+
- name: Run system tests
212+
run: ci/scripts/tests/systemTests.ps1
213+
env:
214+
nvdaLauncherDir: ${{ steps.getLauncher.outputs.download-path }}
215+
- name: Upload system tests results
216+
if: ${{ success() || failure() }}
217+
uses: actions/upload-artifact@v4
218+
with:
219+
name: System tests results
220+
path: testOutput/system
221+
- name: Publish system test report
222+
uses: mikepenz/action-junit-report@v5
223+
if: ${{ success() || failure() }}
224+
with:
225+
check_name: System tests
226+
detailed_summary: true
227+
annotate_only: true
228+
report_paths: testOutput/system/systemTests.xml
229+
230+
cleanupCache:
231+
# Cache deletion on pull_request events cannot occur on PRs from forks
232+
# as PRs from forks do not get write permissions from pull_request events.
233+
# Alternatively, we can change the event trigger to pull_request_target,
234+
# however that might introduce security risks as it grants fork PRs greater permissions.
235+
# In these cases we can always let GitHub handle cache deletion:
236+
# auto deletion after 7 days or limits are hit
237+
name: Cleanup cache
238+
permissions:
239+
actions: write
240+
needs: [checkPot, licenseCheck, unitTests, systemTests]
241+
if: ${{ always() && (github.event.push || github.event.pull_request.head.repo.owner == github.repository_owner) }}
242+
runs-on: ubuntu-latest
243+
steps:
244+
- name: Cleanup cache
245+
shell: bash
246+
run: gh cache delete ${{ github.ref }}-${{ github.run_id }}
247+
env:
248+
GH_TOKEN: ${{ github.token }}
249+
GH_REPO: ${{ github.repository }}
250+
251+
release:
252+
name: Release NVDA
253+
permissions:
254+
contents: write
255+
runs-on: ubuntu-latest
256+
needs: [checkPot, licenseCheck, unitTests, systemTests]
257+
if: startsWith(github.ref_name, 'release-') && !contains(github.ref_name, 'beta')
258+
steps:
259+
- name: Get normalized tag names
260+
id: getReleaseNotes
261+
shell: bash
262+
run: |
263+
echo RELEASE_NAME=$GITHUB_REF_NAME | sed 's/release-//g' >> $GITHUB_OUTPUT
264+
echo NORMALIZED_TAG_NAME=$GITHUB_REF_NAME | sed 's/\./-/g' | sed 's/release-//g' >> $GITHUB_OUTPUT
265+
- name: Get NVDA launcher
266+
uses: actions/download-artifact@v4
267+
with:
268+
name: NVDA launcher
269+
path: output
270+
- name: Publish release
271+
uses: softprops/action-gh-release@v2
272+
with:
273+
prerelease: ${{ contains(github.ref_name, 'rc') }}
274+
make_latest: ${{ !contains(github.ref_name, 'rc') }}
275+
discussion_category_name: ${{ !contains(github.ref_name, 'rc') && 'Releases' || '' }}
276+
name: ${{ steps.getReleaseNotes.outputs.RELEASE_NAME }}
277+
files: output/nvda*.exe
278+
body: Highlights and download links can be found in the [release blog post](https://www.nvaccess.org/post/nvda-${{ steps.getReleaseNotes.outputs.NORMALIZED_TAG_NAME }}/)

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ repos:
147147
types_or: [python, c, c++, batch]
148148
- id: licenseCheck
149149
name: Check license compatibility of pip dependencies
150-
files: ^(requirements\.txt|runlicensecheck\.bat)$
150+
files: ^(requirements\.txt|runlicensecheck\.bat|pyproject.toml)$
151151
entry: ./runlicensecheck.bat
152152
language: script
153153
pass_filenames: false

ci/README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Continuous Integration with GitHub Actions
2+
3+
[Documentation about GitHub Actions](https://docs.github.com/en/actions)
4+
5+
## Builds
6+
7+
Builds will fail if any command has a non-zero exit code.
8+
PowerShell scripts continue on non-terminating errors unless the file is prefixed with `$ErrorActionPreference = "Stop";`.
9+
10+
### Build process
11+
12+
1. Checkout NVDA repository with submodules.
13+
1. Install dependencies (or use cache).
14+
1. Set version and scons variables.
15+
1. Prepare source code.
16+
1. Build launcher.
17+
1. Install NVDA.
18+
1. Prepare for tests.
19+
1. Run tests.
20+
1. Clean up build cache.
21+
1. Release NVDA if this is a tagged release.
22+
23+
## Testing
24+
25+
Before testing we:
26+
27+
* Create directories to store results.
28+
* Install NVDA for system tests
29+
30+
The tests we perform are:
31+
32+
* check translation comments
33+
* license checks
34+
* unit tests
35+
* system tests
36+
37+
## Artifacts
38+
39+
* NVDA launcher.
40+
* Test results.

ci/scripts/installNVDA.ps1

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
$errorCode=0
2+
$nvdaLauncherFile=$(Resolve-Path "$env:nvdaLauncherDir\nvda*.exe")
3+
$nvdaInstallerLogDir=$(Resolve-Path ".\testOutput\install")
4+
$installerLogFilePath="$nvdaInstallerLogDir\nvda_install_temp.log"
5+
$installerCrashDumpPath="$nvdaInstallerLogDir\nvda_crash.dmp"
6+
$installerProcess=Start-Process -FilePath "$nvdaLauncherFile" -ArgumentList "--install-silent --debug-logging --log-file $installerLogFilePath" -passthru
7+
try {
8+
$installerProcess | Wait-Process -Timeout 180 -ErrorAction Stop
9+
$errorCode=$installerProcess.ExitCode
10+
} catch {
11+
Write-Output "NVDA installer process timed out.`n" >> $env:GITHUB_STEP_SUMMARY
12+
$errorCode=1
13+
}
14+
# If the installer failed to exit the log file is still in use.
15+
# We can't/shouldn't upload a file which is locked,
16+
# as a work around create a copy of the log and upload that instead.
17+
Copy-Item $installerLogFilePath "nvda_install.log"
18+
if (Test-Path -Path $installerCrashDumpPath){
19+
Write-Output "NVDA installer process crashed.`n" >> $env:GITHUB_STEP_SUMMARY
20+
$errorCode=1
21+
}
22+
if ($errorCode -ne 0) { $host.SetShouldExit($errorCode) }

ci/scripts/setBuildVersionVars.ps1

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
$ErrorActionPreference = "Stop";
2+
3+
$pythonVersion = (py --version)
4+
Write-Output $pythonVersion
5+
if ($env:GITHUB_REF_TYPE -eq "tag" -and $env:GITHUB_REF_NAME.StartsWith("release-")) {
6+
# Strip "release-" prefix.
7+
$version = $env:GITHUB_REF_NAME.Substring(8)
8+
Write-Output "release=1" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
9+
if ($env:GITHUB_REF_TYPE -eq "tag" -and ($env:GITHUB_REF_NAME.Contains("rc") -or $env:GITHUB_REF_NAME.Contains("beta"))) {
10+
$versionType = "beta"
11+
} else {
12+
$versionType = "stable"
13+
}
14+
} else {
15+
$commitVersion = $env:GITHUB_SHA.Substring(0, 8)
16+
$BUILD_NUMBER = [int]$env:GITHUB_RUN_NUMBER + [int]$env:START_BUILD_NUMBER
17+
if ($env:pullRequestNumber) {
18+
$version = "pr$env:pullRequestNumber-$BUILD_NUMBER,$commitVersion"
19+
} elseif ($env:GITHUB_REF_NAME -eq "master") {
20+
$version = "alpha-$BUILD_NUMBER,$commitVersion"
21+
} else {
22+
$version = "$env:GITHUB_REF_NAME-$BUILD_NUMBER,$commitVersion"
23+
if ($env:GITHUB_REF_NAME.StartsWith("try-release-")) {
24+
Write-Output "release=1" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
25+
}
26+
}
27+
}
28+
if (!$release) {
29+
if ($env:GITHUB_REF_NAME -eq "master") {
30+
$versionType = "snapshot:alpha"
31+
} elseif (!$env:GITHUB_REF_NAME.StartsWith("try-") -and !$env:pullRequestNumber) {
32+
$versionType = "snapshot:$env:GITHUB_REF_NAME"
33+
}
34+
}
35+
Write-Output "version=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
36+
if ($versionType) {
37+
Write-Output "versionType=$versionType" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
38+
}

0 commit comments

Comments
 (0)