Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
760be41fde | ||
|
|
da5d156ebc | ||
|
|
9c0a8a548a | ||
|
|
efe92994f6 |
@@ -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
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
# Chapter 3 generated outputs and private runner identity
|
||||
/build/
|
||||
.runner
|
||||
/latex-manual/build-metadata.tex
|
||||
@@ -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()
|
||||
@@ -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
|
||||
@@ -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."
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -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
|
||||
|
||||
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 72 KiB |