1+ name : Release
2+
3+ on :
4+ push :
5+ tags :
6+ - " v*.*.*"
7+ workflow_dispatch :
8+
9+ permissions :
10+ contents : write
11+
12+ concurrency :
13+ group : release-${{ github.ref }}
14+ cancel-in-progress : false
15+
16+ jobs :
17+ release :
18+ runs-on : windows-latest
19+ timeout-minutes : 30
20+
21+ steps :
22+ - name : Check out repository
23+ uses : actions/checkout@v4
24+ with :
25+ fetch-depth : 0
26+
27+ - name : Set up Java 21
28+ uses : actions/setup-java@v4
29+ with :
30+ distribution : temurin
31+ java-version : " 21"
32+ cache : maven
33+
34+ - name : Verify release version
35+ shell : pwsh
36+ run : |
37+ [xml]$pom = Get-Content -Raw pom.xml
38+ $version = [string]$pom.project.version
39+ if ([string]::IsNullOrWhiteSpace($version)) {
40+ throw "Project version is missing from pom.xml"
41+ }
42+ if ($version.EndsWith("-SNAPSHOT")) {
43+ throw "Release version cannot end with -SNAPSHOT: $version"
44+ }
45+ if ("${{ github.event_name }}" -eq "push") {
46+ $expectedTag = "v$version"
47+ if ($env:GITHUB_REF_NAME -ne $expectedTag) {
48+ throw "Tag $($env:GITHUB_REF_NAME) does not match pom.xml version $expectedTag"
49+ }
50+ }
51+ "JPI_VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
52+ "Validated JPI version $version" | Add-Content $env:GITHUB_STEP_SUMMARY
53+
54+ - name : Verify source comment policy
55+ shell : pwsh
56+ run : powershell -NoProfile -ExecutionPolicy Bypass -File tools/check-no-comments.ps1
57+
58+ - name : Run unit and attach integration tests
59+ run : mvn --batch-mode --no-transfer-progress clean verify
60+
61+ - name : Validate packaged application
62+ shell : pwsh
63+ run : |
64+ $jar = "target/jpi.jar"
65+ if (-not (Test-Path $jar)) {
66+ throw "Release JAR was not produced: $jar"
67+ }
68+ $entries = @(& jar tf $jar)
69+ $required = @(
70+ "META-INF/MANIFEST.MF",
71+ "dev/whitedev/jpi/JpiApplication.class",
72+ "dev/whitedev/jpi/agent/InspectorAgent.class",
73+ "org/objectweb/asm/tree/ClassNode.class",
74+ "org/eclipse/jdt/internal/compiler/tool/EclipseCompiler.class",
75+ "javax/annotation/Nullable.class",
76+ "assets/cfr-0.152.jar",
77+ "assets/vineflower-1.12.0.jar",
78+ "assets/procyon-compilertools-0.6.0.jar",
79+ "assets/procyon-core-0.6.0.jar"
80+ )
81+ foreach ($entry in $required) {
82+ if ($entries -notcontains $entry) {
83+ throw "Release JAR is missing $entry"
84+ }
85+ }
86+ "Validated shaded JAR contents" | Add-Content $env:GITHUB_STEP_SUMMARY
87+
88+ - name : Stage release artifacts
89+ shell : pwsh
90+ run : |
91+ New-Item -ItemType Directory -Force dist | Out-Null
92+ $name = "jpi-v$($env:JPI_VERSION).jar"
93+ $artifact = Join-Path "dist" $name
94+ Copy-Item "target/jpi.jar" $artifact
95+ $hash = (Get-FileHash $artifact -Algorithm SHA256).Hash.ToLowerInvariant()
96+ "$hash $name" | Set-Content -Encoding ascii "$artifact.sha256"
97+ "Artifact: $name" | Add-Content $env:GITHUB_STEP_SUMMARY
98+ "SHA-256: $hash" | Add-Content $env:GITHUB_STEP_SUMMARY
99+
100+ - name : Upload workflow artifact
101+ uses : actions/upload-artifact@v4
102+ with :
103+ name : jpi-v${{ env.JPI_VERSION }}-windows
104+ path : dist/*
105+ if-no-files-found : error
106+ retention-days : 30
107+
108+ - name : Build changelog from commits
109+ if : github.event_name == 'push'
110+ shell : pwsh
111+ run : |
112+ $currentTag = $env:GITHUB_REF_NAME
113+ $previousTag = git tag --merged $currentTag --sort=-version:refname |
114+ Where-Object { $_ -ne $currentTag } |
115+ Select-Object -First 1
116+ $range = if ($previousTag) { "$previousTag..$currentTag" } else { $currentTag }
117+ $commits = @(git log --reverse --pretty=format:"- %s (%h)" $range)
118+ $lines = @(
119+ "## Changelog",
120+ ""
121+ )
122+ if ($previousTag) {
123+ $lines += "Changes since $previousTag:"
124+ } else {
125+ $lines += "Changes included in the first tagged release:"
126+ }
127+ $lines += ""
128+ if ($commits.Count -eq 0) {
129+ $lines += "- No commit messages found"
130+ } else {
131+ $lines += $commits
132+ }
133+ $lines += ""
134+ $notesPath = Join-Path $env:RUNNER_TEMP "release-notes.md"
135+ [IO.File]::WriteAllLines($notesPath, $lines, [Text.UTF8Encoding]::new($false))
136+ "RELEASE_NOTES_PATH=$notesPath" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
137+
138+ - name : Create GitHub release
139+ if : github.event_name == 'push'
140+ uses : softprops/action-gh-release@v2
141+ with :
142+ name : JPI ${{ github.ref_name }}
143+ body_path : ${{ env.RELEASE_NOTES_PATH }}
144+ files : dist/*
145+ fail_on_unmatched_files : true
146+ prerelease : ${{ contains(github.ref_name, '-') }}
0 commit comments