From d44e9bbdd9c6e1798c5b34e53c855e2160c28c14 Mon Sep 17 00:00:00 2001 From: veilor Date: Thu, 30 Apr 2026 13:56:03 +0100 Subject: [PATCH] ci: github actions workflow (build-iso + lint), CONTRIBUTING, CODEOWNERS, PR template MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CI builds in fresh Fedora 43 container — matched pcre2/libselinux/selinux-policy versions, no fix-repo hack needed. Container starts every run from clean state, no zombie collisions. Fastest path to first green ISO. --- .github/CODEOWNERS | 4 + .github/PULL_REQUEST_TEMPLATE.md | 20 +++ .github/workflows/build-iso.yml | 120 ++++++++++++++++++ .github/workflows/lint.yml | 55 ++++++++ CONTRIBUTING.md | 74 +++++++++++ build/Containerfile | 2 +- overlay/etc/os-release.d/veilor | 6 +- .../systemd/system/veilor-firstboot.service | 2 +- 8 files changed, 278 insertions(+), 5 deletions(-) create mode 100644 .github/CODEOWNERS create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/workflows/build-iso.yml create mode 100644 .github/workflows/lint.yml create mode 100644 CONTRIBUTING.md diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..1572f2d --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,4 @@ +* @veilor/maintainers +/kickstart/ @veilor/maintainers +/scripts/selinux/ @veilor/maintainers +/.github/ @veilor/maintainers diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..3a9316f --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,20 @@ +## What + + + +## Why + + + +## Test plan + +- [ ] `ksvalidator kickstart/veilor-os.ks` passes +- [ ] Shellcheck clean on edited scripts +- [ ] Local ISO build succeeds OR CI build green +- [ ] Booted ISO in QEMU via `./test/run-vm.sh` and walked `test/boot-checklist.md` +- [ ] No personal/onyx leaks (`grep -ri 'onyx\|192\.168\.0\.\|fedora\.local'` returns zero) + +## Hardening impact + + diff --git a/.github/workflows/build-iso.yml b/.github/workflows/build-iso.yml new file mode 100644 index 0000000..e1e7a78 --- /dev/null +++ b/.github/workflows/build-iso.yml @@ -0,0 +1,120 @@ +name: Build veilor-os ISO + +on: + push: + branches: [main] + paths: + - 'kickstart/**' + - 'overlay/**' + - 'scripts/**' + - 'assets/**' + - 'build/**' + - '.github/workflows/build-iso.yml' + workflow_dispatch: + inputs: + releasever: + description: 'Fedora release version' + required: false + default: '43' + release: + types: [published] + +jobs: + build: + name: Build live ISO + runs-on: ubuntu-24.04 + timeout-minutes: 90 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Free up disk + run: | + sudo rm -rf /opt/hostedtoolcache /usr/share/dotnet /usr/local/lib/android /usr/local/share/boost + sudo apt-get clean + df -h + + - name: Run build inside Fedora 43 container + uses: addnab/docker-run-action@v3 + with: + image: registry.fedoraproject.org/fedora:43 + options: | + --privileged + -v ${{ github.workspace }}:/work + -v /dev:/dev + --tmpfs /tmp:rw,nosuid,nodev,exec,size=8G + run: | + set -euxo pipefail + + # Update Fedora image to latest packages — guarantees pcre2 + + # libselinux + selinux-policy are matched (the local build's + # core problem). CI runners always start fresh, no version skew. + dnf -y upgrade --refresh + + # Install build tooling + dnf -y install \ + lorax \ + livecd-tools \ + pykickstart \ + anaconda-tui \ + squashfs-tools \ + xorriso \ + createrepo_c \ + git \ + which \ + shadow-utils + + cd /work + + # Validate kickstart syntax + ksvalidator kickstart/veilor-os.ks + + # Run host-native build (CI container has matched lib versions + # so no need for fix-repo or anaconda patching). + mkdir -p build/out + + livemedia-creator \ + --make-iso \ + --no-virt \ + --ks kickstart/veilor-os.ks \ + --resultdir build/out/build \ + --project veilor-os \ + --releasever "${{ github.event.inputs.releasever || '43' }}" \ + --volid VEILOR_OS \ + --tmp /tmp/veilor-lmc \ + --logfile build/out/build.log + + # Move output ISO + checksum + ISO_NAME="veilor-os-${{ github.event.inputs.releasever || '43' }}-$(date +%Y%m%d-%H%M%S).iso" + mv build/out/build/*.iso "build/out/${ISO_NAME}" + cd build/out + sha256sum "${ISO_NAME}" > "${ISO_NAME}.sha256" + ls -lh "${ISO_NAME}" + + - name: Upload ISO artifact + if: success() + uses: actions/upload-artifact@v4 + with: + name: veilor-os-iso + path: | + build/out/*.iso + build/out/*.sha256 + retention-days: 14 + + - name: Upload build log on failure + if: failure() + uses: actions/upload-artifact@v4 + with: + name: veilor-os-buildlog + path: | + build/out/build.log + build/out/build/anaconda/ + + - name: Attach to release + if: github.event_name == 'release' + uses: softprops/action-gh-release@v2 + with: + files: | + build/out/*.iso + build/out/*.sha256 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..61ecda9 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,55 @@ +name: Lint + +on: + push: + branches: [main] + pull_request: + +jobs: + ksvalidate: + name: Kickstart syntax + runs-on: ubuntu-24.04 + container: + image: registry.fedoraproject.org/fedora:43 + steps: + - uses: actions/checkout@v4 + - run: dnf -y install pykickstart + - run: ksvalidator kickstart/veilor-os.ks + + shellcheck: + name: Shell scripts + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + - uses: ludeeus/action-shellcheck@master + with: + severity: warning + ignore_paths: build/cache .github + + brand-leak: + name: No personal/onyx leaks + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + - name: Grep for leaks + run: | + set -e + # Allow audit greps that explicitly check for the patterns + MATCHES=$(grep -rIni \ + -e 'onyx' \ + -e '192\.168\.0\.' \ + -e 'fedora\.local' \ + -e 'xynki\.dev' \ + --exclude-dir=.git \ + --exclude='*.md' \ + . || true) + + # Filter out test/audit lines that legitimately reference patterns + LEAKS=$(echo "$MATCHES" | grep -v -e 'should not contain' -e 'returns zero' -e 'audit grep' || true) + + if [[ -n "$LEAKS" ]]; then + echo "::error::Brand leaks detected" + echo "$LEAKS" + exit 1 + fi + echo "no leaks ✓" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..6864464 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,74 @@ +# Contributing to veilor-os + +## Getting set up + +```bash +git clone https://github.com/veilor/veilor-os.git +cd veilor-os +sudo dnf install lorax livecd-tools pykickstart anaconda-tui squashfs-tools xorriso qemu-kvm edk2-ovmf +``` + +## Build locally + +```bash +./build/build-iso.sh # output: build/out/veilor-os-43-YYYYMMDD-HHMMSS.iso +``` + +Requires sudo (loop devices + chroot mounts). On hosts with a recent +pcre2 / libselinux skew, the build will fail at `selinux-policy %triggerin`; +CI handles this automatically (matched libs in fresh container). + +## Build via CI + +Push to `main` triggers `.github/workflows/build-iso.yml`. Output is +attached as a workflow artifact for 14 days. + +```bash +git push origin main +gh run watch +gh run download --name veilor-os-iso +``` + +## Test the ISO + +```bash +./test/run-vm.sh # boots latest ISO in KVM +SECBOOT=1 ./test/run-vm.sh # boots in OVMF Secure Boot mode +FRESH=1 ./test/run-vm.sh # wipe disk + nvram, fresh install +./test/run-vm.sh build/out/veilor-os-XX.iso # specific ISO +``` + +Walk through `test/boot-checklist.md` before approving a PR. + +## House rules + +1. **No personal data in commits.** No IPs, hostnames, emails, GitHub handles + inside shipped artifacts. CI grep gate enforces. +2. **Hardening parity.** Any change must keep the audit risk score + (`security/audit-template.md`) at or below current baseline. +3. **One feature per PR.** Easier to review, easier to revert. +4. **Follow upstream.** When Fedora changes a package layout, prefer adapting + over forking. We layer veilor on Fedora — we don't fight it. +5. **Caveman mode for commits.** Conventional Commits, ≤50 char subject, + body only when "why" isn't obvious. + +## Branch model + +- `main` — always green CI. Tagged for releases. +- `feat/*`, `fix/*`, `chore/*` — branched off main, PR'd back. +- Direct push to main blocked. + +## Release flow + +```bash +git tag -a v0.2.0 -m "first green ISO" +git push origin v0.2.0 +gh release create v0.2.0 --generate-notes +# CI attaches the built ISO + sha256 to the release automatically +``` + +## Code of conduct + +Be technical, be direct, no drama. Disagree with the design, not the person. +If a contribution introduces a security regression, the PR is closed without +discussion. diff --git a/build/Containerfile b/build/Containerfile index 0904128..5aab84f 100644 --- a/build/Containerfile +++ b/build/Containerfile @@ -1,7 +1,7 @@ FROM registry.fedoraproject.org/fedora:43 LABEL org.opencontainers.image.title="veilor-os build env" -LABEL org.opencontainers.image.source="https://github.com/veilor-uk/veilor-os" +LABEL org.opencontainers.image.source="https://github.com/veilor/veilor-os" RUN dnf install -y \ lorax \ diff --git a/overlay/etc/os-release.d/veilor b/overlay/etc/os-release.d/veilor index 166389e..e305b2a 100644 --- a/overlay/etc/os-release.d/veilor +++ b/overlay/etc/os-release.d/veilor @@ -4,8 +4,8 @@ ID=veilor ID_LIKE=fedora VERSION="0.1" VERSION_ID="0.1" -HOME_URL="https://github.com/veilor-uk/veilor-os" -DOCUMENTATION_URL="https://github.com/veilor-uk/veilor-os/tree/main/docs" -BUG_REPORT_URL="https://github.com/veilor-uk/veilor-os/issues" +HOME_URL="https://github.com/veilor/veilor-os" +DOCUMENTATION_URL="https://github.com/veilor/veilor-os/tree/main/docs" +BUG_REPORT_URL="https://github.com/veilor/veilor-os/issues" ANSI_COLOR="0;30;47" LOGO=veilor-logo diff --git a/overlay/etc/systemd/system/veilor-firstboot.service b/overlay/etc/systemd/system/veilor-firstboot.service index 3a71eab..c397057 100644 --- a/overlay/etc/systemd/system/veilor-firstboot.service +++ b/overlay/etc/systemd/system/veilor-firstboot.service @@ -1,6 +1,6 @@ [Unit] Description=veilor-os first-boot admin password setup -Documentation=https://github.com/veilor-uk/veilor-os +Documentation=https://github.com/veilor/veilor-os ConditionPathExists=!/var/lib/veilor-firstboot.done Before=sddm.service display-manager.service After=systemd-user-sessions.service plymouth-quit-wait.service