diff --git a/latex-manual/devopsAutomatedManualBuild.tex b/latex-manual/devopsAutomatedManualBuild.tex index 679393c..44b84ec 100644 --- a/latex-manual/devopsAutomatedManualBuild.tex +++ b/latex-manual/devopsAutomatedManualBuild.tex @@ -1,124 +1,274 @@ \chapter{Automated Manual Build} \ChapterLabel{AutomatedManualBuild} -\index{Gitea Actions}\index{runner}\index{build artifact} -\begin{devopsNote}[Draft: verification incomplete] -This chapter addresses course assignment Chapter 3. Its chapter number in -this living manual may differ. Vincent reported a successful local build -of the original manual in an Ubuntu VM on October 9, 2026. The new automated -build script, runner registration, Gitea execution and artifact upload require -their own verification. No pending check below is claimed to have passed. +\index{Gitea Actions}\index{runner}\index{build artifact}\index{LaTeX}\index{continuous integration} + +\begin{devopsNote}[Chapter 3 verification status] +This chapter documents the team's Gitea Actions manual builds performed on +October 9--10, 2026. Runs 2 and 3 succeeded, run 4 demonstrates a controlled +LaTeX failure, and run 5 shows recovery. Screenshots and downloadable build +metadata support the reported sequence. The exact failed/repaired commit IDs, +the first compiler-error log line, and the final integrated artifact still +require verification. Jenkins merge checks are a separate Chapter 4 activity. \end{devopsNote} \section{Source and trigger} -Source repository: \url{https://git.137-184-97-250.nip.io/stevens-smartpark/smartpark-app}. -Main source: \texttt{latex-manual/devopsAssignment.tex}. -Workflow: \texttt{.gitea/workflows/manual.yml}. Configured push branches are -\texttt{main}, \texttt{chapter3-build-automation} and \texttt{chapter3-build-test}. -HTTPS Git traffic uses public port 443 at the proxy; the handoff reports -private Gitea port 3000. The external VM uses the public HTTPS hostname, -not the Droplet's private container DNS. The runner needs no public inbound -submission port. \textbf{Pending:} source/workflow commit links, actual push -event and run link, verified network diagram and access path. +The team maintains the complete buildable LaTeX source, bibliography, figures, +and nonsecret build instructions in the Gitea repository: +\url{https://git.137-184-97-250.nip.io/stevens-smartpark/smartpark-app}. +The main document is \texttt{latex-manual/devopsAssignment.tex}; this chapter is +\texttt{latex-manual/devopsAutomatedManualBuild.tex}. The version-controlled +workflow is \texttt{.gitea/workflows/manual.yml}, and the build program is +\texttt{ci/build\_manual.py}. + +The workflow uses the Git push event on \texttt{main}, +\texttt{chapter3-build-automation}, and \texttt{chapter3-build-test}. The +actual demonstration pushes were made to \texttt{chapter3-build-test}. +Gitea Actions run 2 was triggered by a push from \texttt{vincentpenalosa} +and succeeded for commit +\texttt{9fec46a41ef1dcdffb40d0429e19475ba21af41c}: +\url{https://git.137-184-97-250.nip.io/stevens-smartpark/smartpark-app/actions/runs/2}. +Run 3 succeeded for the subsequent source commit +\texttt{e16a6deab277621f860c8a057a80c9737b5eb4b1}: +\url{https://git.137-184-97-250.nip.io/stevens-smartpark/smartpark-app/actions/runs/3}. +These runs demonstrate the configured source-push-to-workflow connection. + +Git clients push over HTTPS to the public Gitea hostname on TCP port 443. +Caddy terminates TLS and forwards the request to Gitea on the private container +port 3000. The runner VM reaches the public HTTPS Gitea hostname and does not +need a public inbound build, compiler, or management port. The runner checks +out source over the network and uploads the artifact through Gitea Actions; +no shared filesystem between the VM and Gitea is needed. + +\begin{figure}[htbp] +\centering +\includegraphics[width=0.92\linewidth]{png/ch3-run2-success.png} +\caption{October 9, 2026 (EDT): push-triggered Gitea Actions run 2 on +\texttt{chapter3-build-test}, showing a successful job and one artifact.} +\label{fig:ch3-push-run2} +\end{figure} \section{Runner setup} -Proposed host: Vincent's Ubuntu 22.04.5 LTS VirtualBox VM, x86\_64, -approximately 4 GB allocated RAM and 25 GB virtual disk. These are -user-reported observations, not a fresh resource measurement. -Proposed repository-scoped runner: Gitea Runner 2.3.0, label -\texttt{smartpark-latex:host}, capacity one, dedicated unprivileged Linux -account. It uses installed tools directly in the VM and does not use Docker. -\textbf{Pending:} final owner/location, installed version, online screenshot, -job assignment, resource measurements, reboot/service test and availability -agreement for grading. Update this section if Nica hosts the runner instead. +The self-managed runner executes on Vincent's separate Ubuntu 22.04.5 LTS +VirtualBox VM (\texttt{x86\_64}), rather than on the shared DigitalOcean +Droplet hosting Gitea and Jenkins. The handoff records approximately 4 GB of +allocated memory and a 25 GB virtual disk; these are historical observations, +not current free-resource measurements. The installed Gitea runner version is +reported as 2.3.0. Its configured name is \texttt{vincent-ubuntu-manual}, +with a repository-scoped registration for the SmartPark repository, label +\texttt{smartpark-latex:host}, and capacity one. The workflow selects the +label through \texttt{runs-on: smartpark-latex}. + +The runner executes jobs in host mode, using TeX and Python utilities installed +on Ubuntu rather than launching Docker job containers. A dedicated unprivileged +\texttt{smartpark-runner} Linux account runs the service. The handoff identifies +\texttt{smartpark-runner.service}, configuration at +\texttt{/etc/smartpark-runner/config.yaml}, and a private runner identity at +\texttt{/var/lib/smartpark-runner/.runner}. A supplied service screenshot shows +the service active; successful jobs 2 and 3 additionally establish that the +runner executed workflow work. The VM must remain running and network-connected +to accept new jobs. No reboot-survival or current resource-availability test is +claimed without separate evidence. + +\begin{figure}[htbp] +\centering +\includegraphics[width=0.92\linewidth]{png/ch3-runner-service.png} +\caption{October 9, 2026 (EDT): Ubuntu service evidence for the separate +Gitea Actions runner VM. Service activity is not, by itself, proof of current +Gitea online status.} +\label{fig:ch3-runner-service} +\end{figure} \section{Reproducible compilation} -Run \texttt{python3 ci/build\_manual.py} from a checkout. The script copies -the source into a fresh temporary directory, invokes \texttt{latexmk -pdf} -with error stopping and shell escape, generates glossary and index, and -finishes the PDF. BibTeX is coordinated by latexmk. Shell escape permits -minted to invoke Pygments; source and workflow authors must be trusted. -Output: \texttt{build/manual/SmartPark-Manual.pdf}. -Nonzero tool exit status, missing PDF and unresolved reference/citation -summaries fail the build. A previous deliverable is removed before building. -\textbf{Pending:} actual command output, successful clean-build log, package -versions from \texttt{build-info.txt}, and reproduction by another teammate. +On a clean Git checkout, the documented entry point is +\texttt{python3 ci/build\_manual.py}. This script copies the manual source to +a fresh temporary work directory and compiles the main file with +\texttt{latexmk -pdf}, stopping on LaTeX errors. It supports the document's +\texttt{minted} highlighting with Pygments and shell escape, and coordinates +bibliography, glossary, index, and repeated LaTeX passes. Source and workflow +edit rights must be restricted because enabling shell escape executes helper +programs. The expected deliverables are +\texttt{build/manual/SmartPark-Manual.pdf} and +\texttt{build/manual/build-info.txt}. + +The supplied successful artifact metadata records \texttt{latexmk} 4.76, +\texttt{pdfTeX} 1.40.22 (TeX Live 2022/dev/Debian), and Pygments 2.11.2. +The handoff also reports \texttt{makeglossaries} 4.49 and packages including +\texttt{texlive-latex-extra}, \texttt{texlive-fonts-recommended}, +\texttt{lmodern}, and \texttt{python3-pygments}. The build script removes old +deliverables, checks command exit status and the expected PDF, and treats +unresolved reference/citation summaries as errors. Therefore, an old PDF +cannot silently stand in for a newly successful build. The compiler runs on +the runner VM, not in the Gitea application container. + +Run 2's successful \texttt{manual} job took 41 seconds; run 3 also completed +successfully. Their run pages and downloadable \texttt{build-info.txt} files +provide the logged build context: +\url{https://git.137-184-97-250.nip.io/stevens-smartpark/smartpark-app/actions/runs/2} +and +\url{https://git.137-184-97-250.nip.io/stevens-smartpark/smartpark-app/actions/runs/3}. +Run 4 is the controlled negative compilation test, with a failed workflow +status. For full error-log evidence, the actual first compiler-error line must +still be quoted from the Run 4 job console; the screenshot alone does not +show that line. \section{PDF version traceability} -The build identification page retains the human-maintained document version -and displays the triggering revision and run number. Local runs display -\texttt{local}; modified local working trees display \texttt{dirty}. -The generated metadata exists only in the temporary build directory. -The workflow never commits or pushes generated metadata. -\textbf{Pending:} screenshot of a real Actions PDF and its matching commit -and run. Local identifiers are not Gitea evidence. +The team maintains the human-readable manual version separately from the +machine-generated build identifier. The documented manual version for these +runs is \texttt{1.9-draft}. For Gitea Actions builds, the identification page +adds the triggering commit's short revision and the workflow run number. +The metadata is generated during the temporary build and is not pushed back +to the branch, avoiding a self-triggering push/build loop. Local builds use +\texttt{local}; local modified trees can display \texttt{dirty}, so a local +build is not substituted for Actions evidence. + +The downloaded PDF for run 2 visibly identifies +\texttt{1.9-draft+build.2.9fec46a41ef1}, source revision +\texttt{9fec46a41ef1}, and workflow run \texttt{2}. The downloaded PDF for +run 3 displays \texttt{1.9-draft+build.3.e16a6deab277}, source revision +\texttt{e16a6deab277}, and workflow run \texttt{3}. The matching full +commits are recorded in Section 6. The respective build metadata timestamps +are October 10, 2026 at 02:12 UTC and 02:26 UTC. A dated screenshot of the +visible identification page should be included in the final evidence set. \section{Downloadable artifact} -The workflow requests an artifact named with the run number and commit, -containing the manual PDF and nonsecret build metadata. It requests 30 days -retention. This request is not proof of the server's applied retention policy. - -Gitea Actions run 2 successfully produced a downloadable manual -artifact from Git commit -\texttt{9fec46a41ef1dcdffb40d0429e19475ba21af41c}. - -The successful workflow run is available at: +The workflow names artifacts using the workflow run and triggering source +commit. Run 2 uploaded a named downloadable artifact: \url{https://git.137-184-97-250.nip.io/stevens-smartpark/smartpark-app/actions/runs/2}. +Its downloaded ZIP contains \texttt{SmartPark-Manual.pdf} and +\texttt{build-info.txt}. The 82-page PDF was extracted and opened +successfully. Its build identifier is +\texttt{1.9-draft+build.2.9fec46a41ef1}, matching run 2 and commit +\texttt{9fec46a41ef1dcdffb40d0429e19475ba21af41c}. Run 3 also +produced a distinct successful PDF and matching metadata, rather than +reusing the previous output. -The downloaded artifact archive contains -\texttt{SmartPark-Manual.pdf} and \texttt{build-info.txt}. -The PDF was downloaded and opened successfully. It contains -82 pages and displays the build identifier -\texttt{1.9-draft+build.2.9fec46a41ef1}. - -The workflow requests 30 days of artifact retention, but the -effective server-side retention policy has not been -independently verified. Build artifacts are not permanent backups. +A team member obtains an artifact by opening the matching Gitea Actions run, +choosing the named entry under Artifacts, downloading and extracting the ZIP, +and visually inspecting the PDF and its identification page. The workflow +requests a 30-day artifact retention period. The server's actually applied +retention policy was not independently verified. Artifacts are downloadable +build deliverables, not permanent backups. +\begin{figure}[htbp] +\centering +\includegraphics[width=0.92\linewidth]{png/ch3-run2-success.png} +\caption{October 9, 2026 (EDT): successful run 2 showing the named downloadable +manual artifact in the Gitea Actions interface.} +\label{fig:ch3-artifact-run2} +\end{figure} \section{Change, failure, and repair evidence} -\textbf{Pending:} fill the evidence worksheet in -\texttt{docs/ch3-evidence.md}, then summarize the real results here. -Include two successive source changes producing successful PDFs and a -controlled LaTeX syntax error followed by repair on a workflow-covered -test branch. Record date, expected and actual result, full commit, run URL, -visible PDF identifier and artifact link. A failed compile must not publish -a successful PDF. Do not substitute Chapter 4 Jenkins tests for these runs. +The team performed the following source-change and repair sequence on +\texttt{chapter3-build-test}. Expected results were compared with the +actual Gitea Actions status, with links to each run. + +\begin{enumerate} +\item \textbf{First successful source change:} run 2, ``Document first manual +build demonstration,'' compiled commit +\texttt{9fec46a41ef1dcdffb40d0429e19475ba21af41c}, generated the PDF +identifier \texttt{1.9-draft+build.2.9fec46a41ef1}, and uploaded one named +artifact. Expected: build and artifact succeed; actual: success. +\url{https://git.137-184-97-250.nip.io/stevens-smartpark/smartpark-app/actions/runs/2}. + +\item \textbf{Second successful source change:} run 3, ``Document second +manual build demonstration,'' compiled the next source change at commit +\texttt{e16a6deab277621f860c8a057a80c9737b5eb4b1}. The downloaded PDF +identifies \texttt{1.9-draft+build.3.e16a6deab277}. Expected: a different +build/PDF tied to this source revision; actual: successful run and matching +PDF metadata. +\url{https://git.137-184-97-250.nip.io/stevens-smartpark/smartpark-app/actions/runs/3}. + +\item \textbf{Controlled compiler failure:} run 4, ``Demonstrate controlled +LaTeX compilation failure,'' used the deliberate undefined command +\verb|\SmartParkIntentionalBuildFailure|. Expected: nonzero LaTeX build status +and no successfully published PDF. The supplied screenshot confirms failed +workflow status and shows no artifact in that view. It does not show the full +commit SHA or the first error-log line; these require transcription from the +matching run before the evidence is considered complete. +\url{https://git.137-184-97-250.nip.io/stevens-smartpark/smartpark-app/actions/runs/4}. + +\item \textbf{Repair:} run 5, ``Revert Demonstrate controlled LaTeX compilation +failure,'' restored a working document. Expected: successful compile and +artifact upload; actual: screenshot shows a successful job and one artifact. +The repair commit SHA and the PDF's visible build identifier still require +confirmation against the Run 5 artifact. +\url{https://git.137-184-97-250.nip.io/stevens-smartpark/smartpark-app/actions/runs/5}. +\end{enumerate} + +\begin{figure}[htbp] +\centering +\includegraphics[width=0.88\linewidth]{png/ch3-failed-run4.png} +\caption{October 9, 2026 (EDT): controlled LaTeX compilation failure recorded +by Gitea Actions run 4. The specific compiler error must be taken from the +run's job log.} +\label{fig:ch3-run4-failure} +\end{figure} +\begin{figure}[htbp] +\centering +\includegraphics[width=0.88\linewidth]{png/ch3-repaired-run5.png} +\caption{October 9, 2026 (EDT): Gitea Actions run 5 succeeding after the +controlled error was reverted, with one downloadable artifact.} +\label{fig:ch3-run5-repair} +\end{figure} \section{Runner and secret boundary} -Only reviewed team workflows should reach this runner. No pull-request -event is configured in this draft. Push-only triggers are not complete -access control: restrict who may push or modify workflows, and review other -workflows that can target the runner label. Host jobs share an account and -environment and can access that account's runner credentials; this is not -isolation between jobs. Use a dedicated VM and unprivileged service account, -no Docker group, no passwordless sudo, no personal Windows shared folders -or SSH keys, and no untrusted jobs. Registration credentials stay outside Git. -\textbf{Pending:} actual edit rights, repository scope, credential storage -controls and nonsecret configuration links. +The Chapter 3 runner uses Vincent's separate Ubuntu VirtualBox VM, not the +shared DigitalOcean Droplet. Its configured repository-scoped registration, +\texttt{smartpark-latex:host} execution label, capacity one, and unprivileged +\texttt{smartpark-runner} service account limit the jobs' intended access. +Host-mode jobs execute directly as that account and are \emph{not} isolated +from each other by disposable Docker containers. Consequently, workflow and +source changes targeting the runner should be restricted to reviewed team +contributors. A push-only trigger and label do not themselves establish an +access-control boundary. + +The service configuration resides at +\texttt{/etc/smartpark-runner/config.yaml}; the private registration identity +resides at \texttt{/var/lib/smartpark-runner/.runner}. Runner registration +tokens, personal SSH keys, passwords and repository secrets must not appear +in Git, job logs, screenshots, or generated PDFs. The operational Passwords +table should contain only ownership and storage hints. No privileged Docker +socket access was granted to the Chapter 3 job environment on the shared +Droplet; doing so would expose the other Docker-hosted Gitea/Jenkins services +to substantial risk. Only outbound HTTPS access to Gitea is required. + +The actual editor/branch permissions should be verified against repository +settings; this report does not claim that every policy was technically +enforced just because it is recommended. The service evidence is shown in +Figure~\ref{fig:ch3-runner-service}; nonsecret configuration lives under +\texttt{ci/} in the Gitea repository. \section{Manual quality and controls} -This is a draft addition, not a completed assignment submission. The draft -history entry identifies the new chapter; existing Hosts and Passwords -tables have not been changed by the installer and require review before -submission. Add the actual runner host, owner, role, outbound access and -availability; document credential ownership and storage hints only. -\textbf{Pending:} table updates, final version/title/date, glossary terms, -citations, dated figures, run hyperlinks, AI assistance review and removal -of every completed placeholder. Preserve truthful notes about any failures. +The version-controlled source, reproducible workflow, host-mode runner, +compiler checks, visible build identifiers, successful PDF artifacts, and +controlled failure/repair are documented above. The manual version used for +the demonstrated builds is \texttt{1.9-draft}. The front matter, title-page +date and dated document-history entry must be checked against the new final +release version before submission; the final released version must be updated +by the team, without altering historical run identifiers. -Troubleshooting: for a queued job check online status and label; for checkout -failure check DNS, HTTPS and repository permissions; for TeX failure inspect -the first compiler error; for upload failure inspect the artifact step and -server/action compatibility. A successful compiler run alone does not prove -artifact upload. The operator checks the runner service, corrects the cause, -and pushes a source correction to produce a new traceable run. +The Hosts table must document the separate Ubuntu runner VM and its operator, +execution purpose, outgoing Gitea HTTPS access, and VM-availability condition. +The Passwords table must record the runner credential custodian and storage +hint only, with no token or private identity contents. The document history +must explicitly identify whether each table was changed or reviewed without +change. Link this chapter, the cited Gitea run pages, and the relevant source +files from that history entry. Add bibliography references for Gitea Actions, +runner setup and artifacts; relevant glossary/index entries include runner, +Gitea Actions, build artifact, and reproducible compilation. -References: \url{https://docs.gitea.com/runner/2/}, -\url{https://docs.gitea.com/runner/2/labels/}, -\url{https://docs.gitea.com/usage/actions/artifacts/}. -Replace or supplement these links with the manual's normal bibliography -entries during editorial review. +\textbf{Troubleshooting:} For queued jobs, check VM power/network access, +runner service status, repository scope, label matching, and capacity. For +checkout failures, check HTTPS/DNS and repository authorization. For compiler +failures, read the first actual TeX error, check paths and dependencies, and +rerun after a committed repair. For missing artifacts, check that +\texttt{build/manual/SmartPark-Manual.pdf} exists and inspect the upload step. +A green compiler step alone does not establish successful artifact upload. +For failure/repair evidence, keep the exact commit, run link, timestamp, and +outcome synchronized across the manual and screenshots. -First automated source-change demonstration.\par - -Second automated source-change demonstration.\par +\textbf{Final submission check:} Commit the integrated LaTeX and PNG files, +verify a new successful Gitea Actions build, download its PDF artifact, open +and inspect every figure and build identifier, and submit that downloaded PDF. +Do not submit an intermediate PDF that still contains missing evidence or +outdated history/Hosts/Passwords information.