Author SHA1 Message Date
vincentpenalosa 760be41fde Merge branch 'chapter3-build-automation' of https://git.137-184-97-250.nip.io/stevens-smartpark/smartpark-app into chapter3-build-automation
Build SmartPark manual / manual (push) Successful in 51s
2026-10-09 23:49:49 -04:00
vincentpenalosa da5d156ebc Trigger manual PDF build 2026-10-09 23:48:44 -04:00
vpenalosa 9c0a8a548a runner screenshots
Build SmartPark manual / manual (push) Successful in 49s
2026-10-09 23:17:10 -04:00
vincentpenalosa efe92994f6 Prepare automated manual build and Chapter 3 draft
Build SmartPark manual / manual (push) Successful in 51s
2026-10-09 21:01:49 -04:00
18 changed files with 662 additions and 1 deletions
+36
View File
@@ -0,0 +1,36 @@
name: Build SmartPark manual
on:
push:
branches:
- main
- chapter3-build-automation
- chapter3-build-test
jobs:
manual:
runs-on: smartpark-latex
timeout-minutes: 20
steps:
- name: Check out the triggering revision
uses: https://github.com/actions/checkout@v4.2.2
with:
ref: ${{ github.sha }}
fetch-depth: 1
persist-credentials: false
- name: Build PDF and record source identity
env:
MANUAL_CI: 'true'
MANUAL_COMMIT: ${{ github.sha }}
MANUAL_RUN_NUMBER: ${{ github.run_number }}
run: python3 ci/build_manual.py
- name: Publish PDF
# v3 uses the legacy artifact protocol commonly supported by Gitea.
# Actual upload compatibility and retention must be verified on this server.
uses: https://github.com/actions/upload-artifact@v3.1.3
with:
name: smartpark-manual-${{ github.run_number }}-${{ github.sha }}
path: |
build/manual/SmartPark-Manual.pdf
build/manual/build-info.txt
if-no-files-found: error
retention-days: 30
+5
View File
@@ -0,0 +1,5 @@
# Chapter 3 generated outputs and private runner identity
/build/
.runner
/latex-manual/build-metadata.tex
+86
View File
@@ -0,0 +1,86 @@
#!/usr/bin/env python3
"""Build only from a fresh temporary copy; publish output only on success."""
from pathlib import Path
import datetime, os, re, shutil, subprocess, tempfile
ROOT = Path(__file__).resolve().parents[1]
SOURCE = ROOT / 'latex-manual'
OUT = ROOT / 'build' / 'manual'
def run(args, cwd=ROOT):
print('+ ' + ' '.join(args), flush=True)
subprocess.run(args, cwd=cwd, check=True)
def git(*args):
return subprocess.check_output(['git', *args], cwd=ROOT, text=True).strip()
def main():
OUT.mkdir(parents=True, exist_ok=True)
# Only remove this script's two fixed output files, so a failed run cannot
# leave a stale deliverable looking successful.
for name in ('SmartPark-Manual.pdf', 'build-info.txt'):
(OUT / name).unlink(missing_ok=True)
sha = git('rev-parse', 'HEAD')
expected = os.environ.get('MANUAL_COMMIT', '')
ci = os.environ.get('MANUAL_CI', '') == 'true'
dirty = bool(git('status', '--porcelain', '--untracked-files=normal'))
if ci and (not expected or expected != sha or dirty):
raise RuntimeError('CI checkout must be clean and match MANUAL_COMMIT')
number = os.environ.get('MANUAL_RUN_NUMBER', 'local')
if ci and not number.isdigit():
raise RuntimeError('Missing numeric Gitea run number')
if not re.fullmatch(r'[A-Za-z0-9.-]+', number):
raise RuntimeError('Unsafe run identifier')
revision = sha[:12] + ('-dirty' if dirty else '')
build_time = datetime.datetime.now(datetime.timezone.utc).strftime('%Y-%m-%d %H:%M UTC')
for tool in ('latexmk', 'pdflatex', 'bibtex', 'makeglossaries', 'makeindex', 'pygmentize'):
if shutil.which(tool) is None:
raise RuntimeError('Missing tool: ' + tool)
with tempfile.TemporaryDirectory(prefix='manual-', dir=ROOT / 'build') as temp:
work = Path(temp)
shutil.copytree(SOURCE, work, dirs_exist_ok=True,
ignore=shutil.ignore_patterns('*.aux', '*.log', '*.pdf', '*.toc', '*.out',
'*.bbl', '*.blg', '*.fdb_latexmk', '*.fls', '*.idx', '*.ind', '*.ilg',
'*.glo', '*.gls', '*.glg', '*.ist', '*.acn', '*.acr', '*.alg',
'*.lof', '*.lot', '_minted-*', 'build-metadata.tex'))
# Do not discard legitimate PDF figures: restore tracked/source PDFs
# except the old root document output.
for source_pdf in SOURCE.rglob('*.pdf'):
if source_pdf == SOURCE / 'devopsAssignment.pdf':
continue
target = work / source_pdf.relative_to(SOURCE)
target.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(source_pdf, target)
(work / 'build-metadata.tex').write_text(
'\\renewcommand{\\BuildRevision}{' + revision + '}\n' +
'\\renewcommand{\\BuildRun}{' + number + '}\n' +
'\\renewcommand{\\BuildUTC}{' + build_time + '}\n', encoding='utf-8')
command = ['latexmk', '-pdf', '-interaction=nonstopmode', '-halt-on-error',
'-file-line-error', '-shell-escape', 'devopsAssignment.tex']
run(command, work)
run(['makeglossaries', 'devopsAssignment'], work)
if (work / 'devopsAssignment.idx').stat().st_size:
run(['makeindex', 'devopsAssignment.idx'], work)
run(command, work)
pdf = work / 'devopsAssignment.pdf'
if not pdf.is_file() or pdf.stat().st_size < 5 or pdf.read_bytes()[:5] != b'%PDF-':
raise RuntimeError('Expected nonempty PDF was not produced')
log = (work / 'devopsAssignment.log').read_text(errors='replace')
if 'There were undefined references' in log or 'There were undefined citations' in log:
raise RuntimeError('PDF still contains unresolved references/citations; inspect source')
shutil.copy2(pdf, OUT / 'SmartPark-Manual.pdf')
info = f'commit={sha}\nrevision={revision}\nrun={number}\nutc={build_time}\n'
info += 'mode=' + ('Gitea Actions' if ci else 'LOCAL TEST - not Actions evidence') + '\n'
for tool, flag in [('latexmk','-v'), ('pdflatex','--version'), ('pygmentize','-V')]:
result = subprocess.check_output([tool, flag], text=True)
info += result
packages = subprocess.check_output(['dpkg-query', '-W',
'-f=${Package}\t${Version}\n', 'latexmk', 'texlive-base',
'texlive-latex-extra', 'texlive-fonts-recommended', 'lmodern', 'python3-pygments'], text=True)
info += '\nUbuntu package versions:\n' + packages
(OUT / 'build-info.txt').write_text(info, encoding='utf-8')
print(info)
print('SUCCESS: ' + str(OUT / 'SmartPark-Manual.pdf'))
if __name__ == '__main__':
main()
+13
View File
@@ -0,0 +1,13 @@
log:
level: info
runner:
file: /var/lib/smartpark-runner/.runner
capacity: 1
timeout: 20m
shutdown_timeout: 25m
labels:
- smartpark-latex:host
cache:
enabled: false
host:
workdir_parent: /var/lib/smartpark-runner/work
+46
View File
@@ -0,0 +1,46 @@
#!/usr/bin/env bash
# Run as your normal Ubuntu user, not as root. Uses sudo for installation.
set -euo pipefail
[[ $(uname -m) == x86_64 ]] || { echo 'This installer targets x86_64 only'; exit 1; }
base=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
[[ ! -e /etc/smartpark-runner/config.yaml ]] || { echo 'Runner already configured; inspect it rather than overwrite.'; exit 1; }
sudo apt-get update
sudo apt-get install --no-install-recommends curl ca-certificates xz-utils
downloads=$(mktemp -d)
cd "$downloads"
# Resolve the current Node 22 release from its official checksum list, then
# install and record that exact release. No downloaded install script is run.
curl -fSLO https://nodejs.org/dist/latest-v22.x/SHASUMS256.txt
node_archive=$(awk '$2 ~ /^node-v22\.[0-9]+\.[0-9]+-linux-x64\.tar\.xz$/ {print $2}' SHASUMS256.txt)
[[ -n "$node_archive" && "$node_archive" != *$'\n'* ]]
node_version=${node_archive#node-}
node_version=${node_version%-linux-x64.tar.xz}
curl -fSLO "https://nodejs.org/dist/$node_version/$node_archive"
awk -v f="$node_archive" '$2 == f' SHASUMS256.txt | sha256sum -c -
tar -xf "$node_archive"
[[ ! -e /opt/smartpark-node ]] || { echo '/opt/smartpark-node exists; inspect before continuing'; exit 1; }
sudo mv "${node_archive%.tar.xz}" /opt/smartpark-node
sudo chown -R root:root /opt/smartpark-node
runner_version=2.3.0
runner_file="gitea-runner-$runner_version-linux-amd64"
curl -fSLO "https://dl.gitea.com/gitea-runner/$runner_version/$runner_file"
curl -fSLO "https://dl.gitea.com/gitea-runner/$runner_version/$runner_file.sha256"
sha256sum -c "$runner_file.sha256"
sudo install -m 0755 "$runner_file" /usr/local/bin/gitea-runner
if id smartpark-runner >/dev/null 2>&1; then
echo 'smartpark-runner account already exists; inspect its permissions before continuing.'
exit 1
fi
sudo useradd --system --create-home --home-dir /var/lib/smartpark-runner --shell /usr/sbin/nologin smartpark-runner
sudo chmod 700 /var/lib/smartpark-runner
sudo install -d -o smartpark-runner -g smartpark-runner -m 700 /var/lib/smartpark-runner/work
sudo install -d -o root -g smartpark-runner -m 750 /etc/smartpark-runner
sudo install -o root -g smartpark-runner -m 640 "$base/runner-config.yaml" /etc/smartpark-runner/config.yaml
sudo install -m 644 "$base/smartpark-runner.service" /etc/systemd/system/smartpark-runner.service
sudo systemctl daemon-reload
sudo -u smartpark-runner /opt/smartpark-node/bin/node --version
sudo -u smartpark-runner /usr/local/bin/gitea-runner --version
sudo -u smartpark-runner latexmk -v
echo 'Installed, but NOT registered or started. Registration requires an authorized token.'
echo "Verified downloads remain in $downloads; remove those files later using the Files app if desired."
+23
View File
@@ -0,0 +1,23 @@
[Unit]
Description=SmartPark Gitea manual runner
After=network-online.target
Wants=network-online.target
[Service]
User=smartpark-runner
Group=smartpark-runner
WorkingDirectory=/var/lib/smartpark-runner
Environment=HOME=/var/lib/smartpark-runner
Environment=PATH=/opt/smartpark-node/bin:/usr/local/bin:/usr/bin:/bin
ExecStart=/usr/local/bin/gitea-runner daemon --config /etc/smartpark-runner/config.yaml
Restart=on-failure
RestartSec=10
UMask=0077
NoNewPrivileges=true
PrivateTmp=true
ProtectHome=true
ProtectSystem=full
TimeoutStopSec=30min
[Install]
WantedBy=multi-user.target
+304
View File
@@ -0,0 +1,304 @@
# SmartPark Chapter 3: local preparation and Gitea handoff
Prepared October 9, 2026. This kit is a draft implementation, not proof that
Gitea Actions is working. The original documentation was reported to compile
successfully in Vincent's Ubuntu VM. The new build script and edited manual
must be tested there. Registration, checkout in Actions, metadata, artifact
upload, retention, and required demonstrations remain pending.
## 1. Apply to Vincent's clean feature branch
Copy this ZIP into Ubuntu's Downloads folder and extract it there. The folder
must contain apply_to_repo.py and payload/. Hidden .gitea files are included
by the installer; do not copy the payload manually.
```bash
cd ~/smartpark-ch3-work/smartpark-app
python3 ~/Downloads/smartpark-ch3-kit/apply_to_repo.py "$PWD"
git diff --stat
git status --short
python3 ci/build_manual.py
```
The installer expects branch chapter3-build-automation, a clean checkout,
and the original version 1.8 source. It refuses changed layouts or existing
target files rather than overwriting them. If it refuses, preserve your work
and inspect the message. It is intended to run once.
Open build/manual/SmartPark-Manual.pdf. Check the new build identification
page, all original chapters, the new eight-section chapter, references,
glossary and index. A first local build should say local and dirty because
your new edits are not committed. It must not show a fabricated Actions run.
The new chapter number follows the existing manual; it addresses assignment
Chapter 3 even if it becomes Chapter 7 in your team's document.
The script removes only its two fixed prior deliverables and builds in a
fresh temporary directory. TeX failures return nonzero, leaving no prior
successful PDF in the publish directory. Console output includes the error;
temporary TeX files are removed after the attempt. Preserve terminal output
if troubleshooting is needed. Do not fix an error by ignoring its exit code.
## 2. Commit locally
Review all new files, including the workflow, before committing. If Git asks
for your identity, set your real name and your chosen Git commit email with
git config user.name and git config user.email (repository-local settings).
```bash
git diff --check
git add .gitignore .gitea/workflows/manual.yml ci docs/ch3-evidence.md docs/CH3-HANDOFF.md latex-manual/devopsAssignment.tex latex-manual/devopsDocumentHistory.tex latex-manual/devopsAutomatedManualBuild.tex
git commit -m "Prepare automated manual build and Chapter 3 draft"
python3 ci/build_manual.py
git status --short
```
After committing, the local PDF should identify that commit without dirty.
git status should be empty. The PDF remains local evidence only.
If using a log with tee, preserve failures with `set -o pipefail` first.
## 3. Prepare a runner (optional now; can be done by Nica later)
This installer targets only the dedicated Ubuntu x86_64 VM. It does not
configure the shared DigitalOcean Droplet. It downloads Node 22 from the
official release server, verifies its listed checksum, and records its exact
version in terminal output. It installs Gitea Runner 2.3.0 with its official
checksum. It creates an unprivileged service account, host-mode label
smartpark-latex:host, capacity one, and a system service. It neither registers
nor starts the runner. Node remains at /opt/smartpark-node/bin/node, not on
your normal user's PATH; the service PATH includes it.
Read ci/setup_runner.sh, then run:
```bash
bash ci/setup_runner.sh
df -h /
```
No Docker, exposed runner port, or Droplet login is needed. If setup fails,
stop at the actual error. It deliberately refuses to replace existing
accounts/configurations, so a partial installation must be inspected before
retrying. Do not blindly delete an existing service account or registration.
The source build tools installed by Vincent are:
```bash
sudo apt-get update
sudo apt-get install --no-install-recommends git python3 latexmk texlive-latex-extra texlive-fonts-recommended lmodern python3-pygments
```
Nica needs those packages if reproducing on her own dedicated Ubuntu host.
Record the actual installed package versions from build-info.txt. A fresh
apt installation may differ from Vincent's; rebuild and verify accordingly.
## 4. Registration: only after authorized Gitea admin help
Have the repository administrator confirm Actions is enabled and provide a
new repository-scoped registration token securely, or assist interactively.
Do not use a personal access token in place of a runner registration token.
Do not share the old Droplet's .runner identity. Registration is performed
on the machine that will execute jobs, with its own new identity.
Run in the Ubuntu VM:
```bash
sudo -u smartpark-runner sh -c 'umask 077; cd /var/lib/smartpark-runner && /usr/local/bin/gitea-runner --config /etc/smartpark-runner/config.yaml register'
```
Interactive answers:
- Instance URL: https://git.137-184-97-250.nip.io (not the repository URL).
- Token: enter it privately at the prompt; do not include it in screenshots.
- Name: vincent-ubuntu-manual (or the actual replacement owner's name).
- Labels: smartpark-latex:host. The supplied config already specifies it.
After successful registration:
```bash
sudo chmod 600 /var/lib/smartpark-runner/.runner
sudo systemctl enable --now smartpark-runner
sudo systemctl status smartpark-runner --no-pager
```
The administrator should confirm the runner appears online and is scoped to
smartpark-app. Review all workflows that may target this runner: push-only
triggers in this file do not prevent another workflow from using its label.
Host-mode jobs are not mutually isolated and can read the service account's
runner identity. Restrict workflow authors to trusted teammates. The service
account has no sudo or Docker group. Do not grant either just to fix a build.
NoNewPrivileges and other service restrictions help limit the account but
are not a sandbox against hostile jobs. Use a dedicated VM without personal
shared folders/keys. Workflow job tokens also require suitable permissions.
## 5. Push the prepared branch
```bash
cd ~/smartpark-ch3-work/smartpark-app
git push -u origin chapter3-build-automation
```
This requires branch write access, not repository Settings access. If denied,
use the handoff in section 9. If a push happened while Actions was disabled,
make a real source correction and push again once enabled. A push-triggered
build is the required evidence, not merely pressing a rerun button.
The workflow must be present on the branch that receives the push. If the
Actions page opens on main, select the branch/run list for your feature
branch. Do not assume an empty main view proves feature workflows are absent.
PR #8 does not have to be merged first. Coordinate eventual merge order so
the documentation and automation are both retained.
In the Actions run, verify checkout SHA, successful compile, and successful
artifact upload. Download the artifact, extract its PDF, and inspect the
visible run number and short SHA against the run and commit. The workflow
requests 30-day retention; ask the administrator what was actually applied.
If upload fails, the assignment is not complete even if the compile is green.
The workflow records checkout v4.2.2 and upload-artifact v3.1.3 as exact tags.
Tags are not immutable commit-SHA pins. The upload action uses the legacy
artifact protocol; its compatibility with this server still needs an actual
test. Do not change blindly to GitHub upload-artifact v4 to fix an error:
check the server's supported protocol/action and preserve the failure log.
## 6. Required success, failure and repair sequence
Use only the dedicated test branch. Start with a clean working tree and a
committed successful preparation. The following changes are intentional,
reviewable source changes. Record each run BEFORE the next push.
```bash
git switch -c chapter3-build-test
printf '\nFirst automated source-change demonstration.\\par\n' >> latex-manual/devopsAutomatedManualBuild.tex
git add latex-manual/devopsAutomatedManualBuild.tex
git commit -m "Document first manual build demonstration"
git push -u origin chapter3-build-test
```
Wait for success. Download PDF #1 and record the commit/run/version/artifact.
```bash
printf '\nSecond automated source-change demonstration.\\par\n' >> latex-manual/devopsAutomatedManualBuild.tex
git add latex-manual/devopsAutomatedManualBuild.tex
git commit -m "Document second manual build demonstration"
git push
```
Wait for success. Download PDF #2 and record matching evidence. Now create
the controlled error on this test branch:
```bash
printf '\n\\SmartParkIntentionalBuildFailure\n' >> latex-manual/devopsAutomatedManualBuild.tex
git add latex-manual/devopsAutomatedManualBuild.tex
git commit -m "Demonstrate controlled LaTeX compilation failure"
git push
```
Wait for the failed compile, preserve the error/run/commit and confirm the
upload step did not publish a successful PDF. Then repair by reverting only
that latest failure commit. Run the following ONLY while that failure commit
is still HEAD and the working tree is clean:
```bash
git log -1 --oneline
git status --short
git revert --no-edit HEAD
git push
```
Capture the repaired successful run and PDF. Fill docs/ch3-evidence.md with
real results and transfer them into the manual chapter. Replace demonstration
sentences with the actual findings in a later editorial commit.
## 7. Complete the manual
The eight sections are skeletons. Keep earlier chapters and fill actual
runner, network and security details, source/run/artifact links, dated
screenshots, expected/actual outcomes, and failed-build troubleshooting.
Update Hosts and Passwords-hints tables and explicitly record their changes.
Review document version, date, title and assignment number (the older title
and assignment number were deliberately preserved for team decision), add
bibliography/glossary entries, and log AI assistance per team conventions.
The added history row is a draft with human review pending.
Arrange peer review and merge through the normal process. Do not bypass
Jenkins required checks or branch protections. After integration into main,
confirm its push-triggered run and download the final artifact. Submit only
the PDF extracted from that successful Actions artifact, not this kit or a
local PDF. The source/script preparation alone is not submission-ready.
## 8. Availability and troubleshooting
- A user service terminal is not needed: systemd starts the runner when Ubuntu
boots. The VM and Windows computer must still be awake and connected.
- Disable automatic suspend in Ubuntu's Power settings while running jobs;
keep Windows awake during agreed build/grading periods. A laptop is not
an always-on server unless you actually keep it available.
- Reboot the VM after initial success, check service status and online state,
and push a harmless source correction to verify recovery.
- Queued: check online status, repository scope and exact smartpark-latex label.
- Checkout: check network/TLS and job-token repository permissions. Do not
disable certificate checks or insert a personal token into the workflow.
- JavaScript/action error: confirm the service's /opt/smartpark-node/bin/node
exists; inspect the action's compatibility and runner logs.
- TeX: fix the first real error. Undefined references may be inherited source
problems; resolve them rather than remove the quality check.
- Artifact: inspect the separate upload step, server protocol and access.
- Logs: sudo journalctl -u smartpark-runner -n 80 --no-pager (review/redact
before sharing). Never dump all environment variables or the .runner file.
- Stop: sudo systemctl stop smartpark-runner. Retire: disable service and ask
an administrator to remove the registration; never send identity files.
## 9. Handoff to Nica if access is unavailable
Commit the prepared files before packaging. Use the branch containing the
latest completed, repaired work. This archives tracked source only and
excludes runner credentials, build output and your Git login settings:
```bash
git status --short
git log -1 --oneline
git archive --format=zip --output="$HOME/Downloads/smartpark-ch3-source-handoff.zip" HEAD
```
Also create a Git bundle of the current branch so Nica can retain commit
identity (the build script requires a Git checkout):
```bash
git bundle create "$HOME/Downloads/smartpark-ch3.git.bundle" HEAD
git bundle verify "$HOME/Downloads/smartpark-ch3.git.bundle"
```
Send that ZIP and Git bundle plus a short factual status: commit ID, actual local test
result, who will host the runner, what needs registration, and which Gitea
checks remain pending. The ZIP includes docs/CH3-HANDOFF.md and the evidence
worksheet. If Nica will host it, she follows the same setup and registers a
new identity on her host; do not copy /var/lib/smartpark-runner/.runner.
If branch access works, prefer a pushed branch and PR link for review.
If Nica receives only these files, she can start a NEW checkout (destination
must not already exist) from the bundle without depending on your laptop:
```bash
git clone ~/Downloads/smartpark-ch3.git.bundle ~/smartpark-ch3-takeover
cd ~/smartpark-ch3-takeover
git switch -c chapter3-nica-takeover
git remote set-url origin https://git.137-184-97-250.nip.io/stevens-smartpark/smartpark-app.git
```
This already includes the applied changes; do not run the kit installer again.
She must add chapter3-nica-takeover to the workflow's push branch list if
testing pushes on that branch. She should inspect the bundle/source contents
before running scripts. The source ZIP is for browsing/import only; a plain
unpacked ZIP does not provide the Git commit information the build requires.
## Official references and verification limits
- https://docs.gitea.com/runner/2/installation/binary/
- https://docs.gitea.com/runner/2/registration/
- https://docs.gitea.com/runner/2/labels/
- https://docs.gitea.com/usage/actions/artifacts/
- https://nodejs.org/dist/latest-v22.x/
The local Ubuntu VM is separate from the assistant's Windows workspace.
This kit was prepared there; actual TeX compilation, Linux installation,
service operation and Gitea behavior must be verified in the real environment.
+18
View File
@@ -0,0 +1,18 @@
# Chapter 3 evidence worksheet
Prepared 2026-10-09. This table is deliberately unfilled. Record real results.
| Date/time | Branch | Full commit | Run URL and number | Expected | Actual | PDF visible ID | Artifact/download proof |
|---|---|---|---|---|---|---|---|
| Pending | chapter3-build-test | Pending | Pending | Success 1 | Pending | Pending | Pending |
| Pending | chapter3-build-test | Pending | Pending | Success 2 | Pending | Pending | Pending |
| Pending | chapter3-build-test | Pending | Pending | Controlled TeX failure | Pending | No new successful PDF | Pending |
| Pending | chapter3-build-test | Pending | Pending | Repair success | Pending | Pending | Pending |
Also retain: runner online/assigned job, nonsecret config, package versions,
actual retention policy, resource measurements, service restart test,
permissions review, PDF visual review, review/merge links and final artifact.
User reported the original source compiled locally on Ubuntu with latexmk
4.76, pdfTeX 1.40.22, Pygments 2.11.2 and makeglossaries 4.49.
That is not proof of this new script or any Gitea execution.
+19 -1
View File
@@ -41,7 +41,14 @@
% Replace these values for each assignment.
\newcommand{\AssignmentTitle}{Domain Names, SSL, and Versioning}
\newcommand{\AssignmentNumber}{\#4}
\newcommand{\DocumentVersion}{1.8}
\newcommand{\DocumentVersion}{1.9-draft}
% Generated only in the disposable build workspace; never committed.
\newcommand{\BuildRevision}{unrecorded}
\newcommand{\BuildRun}{local}
\newcommand{\BuildUTC}{unrecorded}
\InputIfFileExists{build-metadata.tex}{}{}
\newcommand{\DocumentStatus}{Draft}
\newcommand{\CourseNumber}{SSW 590}
\newcommand{\CourseName}{DevOps}
@@ -97,6 +104,16 @@
\pagenumbering{roman}
\singlespacing
\include{prologue}
\clearpage
\section*{Build identification}
\noindent Manual version: \DocumentVersion\par
\noindent Build identifier: \texttt{\DocumentVersion+build.\BuildRun.\BuildRevision}\par
\noindent Source revision: \texttt{\BuildRevision}\par
\noindent Workflow run: \texttt{\BuildRun}\par
\noindent Built: \BuildUTC\par
\noindent A run marked local or a revision marked dirty is a local test,
not evidence of a successful Gitea Actions run.\par
\clearpage
\setcounter{page}{1}
\pagenumbering{arabic}
@@ -119,6 +136,7 @@
\include{devopsLaTeXDocker}
\include{devopsProjectProposal}
\include{devopsGitea}
\include{devopsAutomatedManualBuild}
+104
View File
@@ -0,0 +1,104 @@
\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.
\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.
\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.
\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.
\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.
\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.
\textbf{Pending:} verified artifact upload compatibility, actual retention,
run/artifact link, download and visual inspection. Artifacts are not backups.
\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.
\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.
\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.
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.
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.
+8
View File
@@ -22,6 +22,14 @@ link each entry to the changed chapter, table, figure, or controlled artifact.
\bottomrule
\endlastfoot
October 9, 2026 / 1.9-draft & CDX; VP review pending &
Prepared host-mode manual build automation, generated build identification
and an eight-section Automated Manual Build draft. Execution and Gitea
evidence remain pending. Existing Hosts and Passwords tables are unchanged;
runner entries and credential hints still require review. &
\ChapterRef{AutomatedManualBuild}\\
September 30, 2026 / 1.8 & NS, VP, CDX &
Merged the team's supplied Gitea Sections 6.1--6.4 with the documented
Sections 6.5--6.8. Preserved the reported Student Pack approval and pending
Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB