Files
lab/.gitea/workflows/ci.yml
Michal b26733015f
All checks were successful
CI/CD / typecheck (pull_request) Successful in 47s
CI/CD / lint (pull_request) Successful in 1m11s
CI/CD / test (pull_request) Successful in 1m11s
CI/CD / build (pull_request) Successful in 1m24s
CI/CD / publish-rpm (pull_request) Has been skipped
CI/CD / publish-deb (pull_request) Has been skipped
CI: the nfpm sed pointed at a binary name that no longer exists
nfpm.yaml ships ./dist/labctl; the workflow's sed rewrote
`src: ./dist/lab` -- a pattern that matches nothing -- so nfpm looked for
./dist/labctl, which the bun bundle steps never produce. This job had
never run before (every earlier run died at pnpm setup), so the drift
was invisible. Rewrite the pattern the file actually contains.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V6HNx6cyr4J4CiMGCy1wkF
2026-10-14 19:18:41 +01:00

287 lines
8.7 KiB
YAML

name: CI/CD
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
GITEA_REGISTRY: 10.0.0.194:3012
GITEA_PUBLIC_URL: https://mysources.co.uk
GITEA_OWNER: michal
# ============================================================
# Required Gitea secrets:
# PACKAGES_TOKEN -- Gitea API token (packages + registry)
# ============================================================
jobs:
# -- CI checks (run in parallel on every push/PR) ----------
lint:
runs-on: ubuntu-latest
defaults:
run:
working-directory: bastion
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
package_json_file: bastion/package.json
- uses: actions/setup-node@v4
with:
node-version: 22
- run: pnpm install --frozen-lockfile
- name: Lint
run: pnpm lint || echo "::warning::Lint has errors -- not blocking CI yet"
typecheck:
runs-on: ubuntu-latest
defaults:
run:
working-directory: bastion
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
package_json_file: bastion/package.json
- uses: actions/setup-node@v4
with:
node-version: 22
- run: pnpm install --frozen-lockfile
- name: Generate Prisma client (labd typecheck needs it)
run: pnpm -C src/labd run db:generate
- name: Typecheck
run: pnpm typecheck
test:
runs-on: ubuntu-latest
defaults:
run:
working-directory: bastion
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
package_json_file: bastion/package.json
- uses: actions/setup-node@v4
with:
node-version: 22
- run: pnpm install --frozen-lockfile
- name: Generate Prisma client (labd typecheck needs it)
run: pnpm -C src/labd run db:generate
- name: Install test validators (ubuntu-autoinstall parses YAML via python, kickstart.test runs ksvalidator, the bastion smoke start runs `ip route`)
# pykickstart is not in the runner image's apt sources -- pip it is.
run: |
sudo apt-get update -qq && sudo apt-get install -y -qq python3-yaml python3-pip iproute2
sudo pip3 install --quiet --break-system-packages pykickstart
- name: Build (needed by completions check)
run: pnpm build
- name: Run tests
run: pnpm test:run
# -- Build & package (both architectures) -------------------
build:
runs-on: ubuntu-latest
needs: [lint, typecheck, test]
defaults:
run:
working-directory: bastion
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
package_json_file: bastion/package.json
- uses: actions/setup-node@v4
with:
node-version: 22
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate Prisma client (labd typecheck needs it)
run: pnpm -C src/labd run db:generate
- name: Build all packages
run: pnpm build
- name: Generate shell completions
run: pnpm completions:generate
- uses: oven-sh/setup-bun@v2
- name: Install nfpm
run: |
curl -sL -o /tmp/nfpm.tar.gz "https://github.com/goreleaser/nfpm/releases/download/v2.45.0/nfpm_2.45.0_Linux_x86_64.tar.gz"
tar xzf /tmp/nfpm.tar.gz -C /usr/local/bin nfpm
- name: Bundle x86_64 binary
run: |
mkdir -p dist
bun build src/cli/src/index.ts --compile --target=bun-linux-x64 --outfile dist/lab-x86_64
- name: Bundle arm64 binary
run: |
bun build src/cli/src/index.ts --compile --target=bun-linux-arm64 --outfile dist/lab-arm64
- name: Package x86_64 RPM + DEB
run: |
sed -e 's|^arch:.*|arch: amd64|' -e 's|src: ./dist/labctl$|src: ./dist/lab-x86_64|' nfpm.yaml > /tmp/nfpm-x86_64.yaml
nfpm pkg --config /tmp/nfpm-x86_64.yaml --packager rpm --target dist/
nfpm pkg --config /tmp/nfpm-x86_64.yaml --packager deb --target dist/
- name: Package arm64 RPM + DEB
run: |
sed -e 's|^arch:.*|arch: arm64|' -e 's|src: ./dist/labctl$|src: ./dist/lab-arm64|' nfpm.yaml > /tmp/nfpm-arm64.yaml
nfpm pkg --config /tmp/nfpm-arm64.yaml --packager rpm --target dist/
nfpm pkg --config /tmp/nfpm-arm64.yaml --packager deb --target dist/
- name: Upload RPM artifacts
uses: actions/upload-artifact@v3
with:
name: rpm-packages
path: bastion/dist/lab-*.rpm
retention-days: 7
- name: Upload DEB artifacts
uses: actions/upload-artifact@v3
with:
name: deb-packages
path: bastion/dist/lab*.deb
retention-days: 7
# -- Release pipeline (main branch push only) --------------
publish-rpm:
runs-on: ubuntu-latest
needs: [build]
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
defaults:
run:
working-directory: bastion
steps:
- uses: actions/checkout@v4
- name: Download RPM artifacts
uses: actions/download-artifact@v3
with:
name: rpm-packages
path: bastion/dist/
- name: Install rpm tools
run: sudo apt-get update && sudo apt-get install -y rpm
- name: Publish RPMs to Gitea
env:
GITEA_TOKEN: ${{ secrets.PACKAGES_TOKEN }}
GITEA_URL: http://${{ env.GITEA_REGISTRY }}
GITEA_OWNER: ${{ env.GITEA_OWNER }}
GITEA_REPO: lab
run: |
for RPM_FILE in dist/lab-*.rpm; do
[ -f "$RPM_FILE" ] || continue
RPM_VERSION=$(rpm -qp --queryformat '%{VERSION}-%{RELEASE}' "$RPM_FILE")
RPM_ARCH=$(rpm -qp --queryformat '%{ARCH}' "$RPM_FILE")
echo "Publishing $RPM_FILE (version $RPM_VERSION, arch $RPM_ARCH)..."
# Delete existing version if present
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: token ${GITEA_TOKEN}" \
"${GITEA_URL}/api/v1/packages/${GITEA_OWNER}/rpm/lab/${RPM_VERSION}")
if [ "$HTTP_CODE" = "200" ]; then
echo "Version exists, replacing..."
curl -s -o /dev/null -X DELETE \
-H "Authorization: token ${GITEA_TOKEN}" \
"${GITEA_URL}/api/v1/packages/${GITEA_OWNER}/rpm/lab/${RPM_VERSION}"
fi
# Upload
curl --fail -X PUT \
-H "Authorization: token ${GITEA_TOKEN}" \
--upload-file "$RPM_FILE" \
"${GITEA_URL}/api/packages/${GITEA_OWNER}/rpm/upload"
echo "Published $RPM_FILE successfully!"
done
# Link package to repo
source scripts/link-package.sh
link_package "rpm" "lab"
publish-deb:
runs-on: ubuntu-latest
needs: [build]
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
defaults:
run:
working-directory: bastion
steps:
- uses: actions/checkout@v4
- name: Download DEB artifacts
uses: actions/download-artifact@v3
with:
name: deb-packages
path: bastion/dist/
- name: Publish DEBs to Gitea
env:
GITEA_TOKEN: ${{ secrets.PACKAGES_TOKEN }}
GITEA_URL: http://${{ env.GITEA_REGISTRY }}
GITEA_OWNER: ${{ env.GITEA_OWNER }}
GITEA_REPO: lab
run: |
# Publish to each supported distribution
DISTRIBUTIONS="trixie forky noble plucky"
for DEB_FILE in dist/lab*.deb; do
[ -f "$DEB_FILE" ] || continue
DEB_VERSION=$(dpkg-deb --field "$DEB_FILE" Version)
DEB_ARCH=$(dpkg-deb --field "$DEB_FILE" Architecture)
echo "Publishing $DEB_FILE (version $DEB_VERSION, arch $DEB_ARCH)..."
for DIST in $DISTRIBUTIONS; do
echo " -> $DIST..."
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
-X PUT \
-H "Authorization: token ${GITEA_TOKEN}" \
--upload-file "$DEB_FILE" \
"${GITEA_URL}/api/packages/${GITEA_OWNER}/debian/pool/${DIST}/main/upload")
if [ "$HTTP_CODE" = "201" ] || [ "$HTTP_CODE" = "200" ]; then
echo " Published to $DIST"
elif [ "$HTTP_CODE" = "409" ]; then
echo " Already exists in $DIST (skipping)"
else
echo " WARNING: Upload to $DIST returned HTTP $HTTP_CODE"
fi
done
done
echo "Published successfully!"
# Link package to repo
source scripts/link-package.sh
link_package "debian" "lab"