Develop #8

Merged
iparenteau merged 5 commits from develop into master 2026-09-04 17:50:27 -05:00
5 changed files with 45 additions and 5 deletions

No files matched your search

+2
View File
@@ -31,3 +31,5 @@ tags
/.run/
/out/
*.awk
# Required source for the Jenkins release-notes appendix.
!/scripts/release-notes.awk
Vendored
+3 -3
View File
@@ -71,8 +71,8 @@ pipeline {
steps {
script {
String gitCredentials = scm.userRemoteConfigs[0].credentialsId
if (!gitCredentials) { error('Release builds require an SCM SSH credential with permission to push tags') }
sshagent(credentials: [gitCredentials]) {
if (!gitCredentials) { error('Release builds require an SCM HTTPS username/password credential with permission to push tags') }
withCredentials([gitUsernamePassword(credentialsId: gitCredentials, gitToolName: scm.gitTool ?: 'Default')]) {
sh 'mkdir -p target && sh scripts/release-notes.sh generate "$BUILD_VERSION" > target/release-notes.md'
}
}
@@ -102,7 +102,7 @@ pipeline {
when { branch pattern: 'release/**', comparator: 'GLOB' }
steps {
script {
sshagent(credentials: [scm.userRemoteConfigs[0].credentialsId]) {
withCredentials([gitUsernamePassword(credentialsId: scm.userRemoteConfigs[0].credentialsId, gitToolName: scm.gitTool ?: 'Default')]) {
sh 'sh scripts/release-notes.sh publish "$BUILD_VERSION"'
}
}
+1 -1
View File
@@ -165,7 +165,7 @@ The `Build LaTeX` stage runs only on branches matching `release/**` and compiles
Every successful `release/**` build records a release with an immutable Git tag named `portal-release-${BUILD_VERSION}`. The `Build LaTeX` stage also generates and archives `target/release-notes.md`, listing commit subjects and hashes since the nearest earlier release tag reachable from the current commit. The first recorded release includes the full history; a rebuild without new commits reports no source changes. Before compiling, the same stage uses `awk` to generate `docs/src/appendix/ReleaseNotes.tex`, which `portal.tex` includes immediately after the Revisions appendix. The generated TeX is archived alongside the PDF and Markdown. Commit text is escaped for LaTeX. Local builds use a placeholder until release notes are generated. The agent needs `awk` on its path. Notes are generated from Git history, so their detail depends on the commit messages.
The final `Tag release` stage pushes the tag only after the preceding build, PDF, and applicable Maven deployment stages succeed. Notes archived before a later failure are build artifacts, not a completed release marker. Failed builds do not publish a new release tag. The helper fetches release tags and expands shallow history before comparison. Jenkins needs the SSH Agent plugin, `ssh-agent` on the agent, a trusted Git server host key, and the checkout SCM SSH credential with permission to push tags. Tag conflicts fail the build; existing remote tags are never overwritten. Existing releases without this tag prefix are not comparison baselines.
The final `Tag release` stage pushes the tag only after the preceding build, PDF, and applicable Maven deployment stages succeed. Notes archived before a later failure are build artifacts, not a completed release marker. Failed builds do not publish a new release tag. The helper fetches release tags and expands shallow history before comparison. Jenkins uses HTTPS checkout and the Git plugin's `gitUsernamePassword` binding to reuse the checkout SCM username/password credential for fetching and pushing release tags. The credential must have permission to push tags (a Gitea access token may be stored as its password). Git uses the SCM tool configuration, falling back to `Default`. No SSH Agent plugin is required. Tag conflicts fail the build; existing remote tags are never overwritten. Existing releases without this tag prefix are not comparison baselines.
| Branch | Version | Publish to Nexus |
| --- | --- | --- |
+1 -1
View File
@@ -65,7 +65,7 @@ The multibranch pipeline in \filename{Jenkinsfile} uses JDK \JavaVersion, Maven
\section{Changes Between Releases}
Each successful build on \command{release/**} records a release using an immutable Git tag with prefix \command{portal-release-} followed by its build version. Release notes are saved to \filename{target/release-notes.md}. The \command{Build LaTeX} stage converts them with \command{awk} into \filename{appendix/ReleaseNotes.tex} before compilation. The master document includes this generated appendix immediately after Revisions. The stage archives the PDF, Markdown, and generated TeX. The agent needs \command{awk} on its path. Local builds use a placeholder when release notes have not been generated. Notes list commit messages and hashes since the nearest earlier release tag in the current branch's history. The first recorded release includes the full history; a rebuild without new commits reports no source changes.
The final \command{Tag release} stage pushes the tag after the build, documentation, and applicable Maven deployment succeed. Notes archived before a later failure do not mark a completed release. Jenkins needs the SSH Agent plugin, the \command{ssh-agent} executable, a trusted Git server host key, and an SCM SSH credential permitted to push tags. The helper fetches release tags and completes shallow history before comparing commits. Tag conflicts fail the build without overwriting existing remote tags.
The final \command{Tag release} stage pushes the tag after the build, documentation, and applicable Maven deployment succeed. Notes archived before a later failure do not mark a completed release. Jenkins uses HTTPS checkout and the Git plugin credential binding to reuse the SCM username/password credential for release operations. The credential must permit pushing tags; a Gitea access token can be stored as its password. No SSH Agent plugin is required. The helper fetches release tags and completes shallow history before comparing commits. Tag conflicts fail the build without overwriting existing remote tags.
\section{Building This Manual}
Jenkins runs the \command{Build LaTeX} stage after the application build only on branches matching \command{release/**}. PDF compilation and archiving are skipped on all other branches. The agent needs \command{pdflatex} on its path and the packages used by this manual. It compiles \filename{docs/src/portal.tex} three times, stopping on compilation errors, and writes the PDF to \filename{target/latex/portal.pdf}. The same stage archives that PDF with fingerprinting before workspace cleanup. This pipeline uses \command{pdflatex} directly; \command{latexmk} and Perl are unnecessary.
+38
View File
@@ -0,0 +1,38 @@
# Convert the Markdown emitted by release-notes.sh to a safe LaTeX appendix.
# Escape character by character so commit messages cannot become TeX commands.
function tex(value, result, i, c) {
result = ""
for (i = 1; i <= length(value); i++) {
c = substr(value, i, 1)
if (c == "\\") result = result "\\textbackslash{}"
else if (c == "{" || c == "}" || c == "$" || c == "&" || c == "#" || c == "_" || c == "%") result = result "\\" c
else if (c == "~") result = result "\\textasciitilde{}"
else if (c == "^") result = result "\\textasciicircum{}"
else if (c == "`") result = result "\\textasciigrave{}"
else result = result c
}
return result
}
BEGIN {
print "% Generated by the Build LaTeX stage; do not edit."
print "\\chapter{Release Notes}"
print "\\label{release-notes}"
print "\\begingroup\\raggedright"
}
/^# Changes in / {
print "\\section*{" tex(substr($0, 3)) "}"
next
}
/^- / {
if (!items) { print "\\begin{itemize}"; items = 1 }
print "\\item " tex(substr($0, 3))
next
}
{
if (items) { print "\\end{itemize}"; items = 0 }
print tex($0)
}
END {
if (items) print "\\end{itemize}"
print "\\endgroup"
}