Files

178 lines
5.9 KiB
YAML

name: Release Build Smoke Test
# Validates that the release tarball can be built successfully. This catches
# release-script-specific issues (e.g. overly broad rsync excludes that omit
# frontend source files) before they reach main, instead of failing late in the
# release workflow.
#
# On a push to dev the tarball this job builds is not thrown away: it is
# published as a GitHub pre-release tagged v<VERSION>-dev.<sha7>, so the Cloud
# release lab can install and upgrade-test a dev commit on a real server
# before anything is promoted to main. Only the newest few dev builds are
# kept; older ones and their tags are deleted. Pull-request runs still only
# prove the build.
# main is deliberately absent from `push`: on a merge to main, release.yml's
# `build-release` job runs this very script for real moments later, so building
# the tarball here too was pure duplication.
on:
push:
branches: [dev]
paths:
- 'frontend/**'
- 'backend/**'
- 'scripts/**'
- 'Dockerfile'
- '.dockerignore'
- '.github/workflows/release-smoke.yml'
- '.github/workflows/release.yml'
- 'VERSION'
pull_request:
branches: [main]
paths:
- 'frontend/**'
- 'backend/**'
- 'scripts/**'
- 'Dockerfile'
- '.dockerignore'
- '.github/workflows/release-smoke.yml'
- '.github/workflows/release.yml'
- 'VERSION'
concurrency:
group: release-smoke-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
build-release-smoke:
name: Build release tarball
runs-on: ubuntu-latest
outputs:
dev_tag: ${{ steps.dev.outputs.tag }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
persist-credentials: false
# A dev build carries the commit in its version, so the lab records it
# under a name that is unique, sorts after the release it is based on,
# and is what the installed panel reports as its own version.
- name: Name the dev build
id: dev
if: github.event_name == 'push'
run: |
base=$(tr -d '[:space:]' < VERSION)
version="${base}-dev.$(git rev-parse --short=7 HEAD)"
echo "$version" > VERSION
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "tag=v$version" >> "$GITHUB_OUTPUT"
echo "Dev build: v$version"
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
- name: Install build dependencies
run: |
sudo apt-get update
sudo apt-get install -y python3-venv python3-pip rsync
- name: Run release build script
env:
BUILD_ARCH: amd64
run: bash scripts/build-release.sh
- name: Save the dev release files
if: github.event_name == 'push'
uses: actions/upload-artifact@v4
with:
name: dev-release
path: |
serverkit-*.tar.gz
checksums.txt
if-no-files-found: error
retention-days: 1
publish-dev:
name: Publish dev pre-release
if: github.event_name == 'push' && github.ref == 'refs/heads/dev'
needs: build-release-smoke
runs-on: ubuntu-latest
permissions:
contents: write
steps:
# No checkout or repository scripts run with the write token.
- name: Download the built release files
uses: actions/download-artifact@v4
with:
name: dev-release
- name: Publish the dev build as a pre-release
if: github.event_name == 'push'
uses: softprops/action-gh-release@v3
with:
tag_name: ${{ needs.build-release-smoke.outputs.dev_tag }}
target_commitish: ${{ github.sha }}
name: Dev build ${{ needs.build-release-smoke.outputs.dev_tag }}
prerelease: true
draft: false
files: |
serverkit-*.tar.gz
checksums.txt
body: |
Automated build of dev commit ${{ github.sha }} for the ServerKit Cloud release lab.
Not a release. Do not install this on a server you care about.
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Keep only the newest dev builds
if: github.event_name == 'push'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
KEEP: "3"
run: |
gh release list --repo "$GITHUB_REPOSITORY" --limit 200 \
--json tagName,isPrerelease,createdAt \
--jq '[.[] | select(.isPrerelease and (.tagName | test("-dev\\.")))] | sort_by(.createdAt) | reverse | .['"$KEEP"':] | .[].tagName' \
| while read -r tag; do
[ -n "$tag" ] || continue
echo "Removing old dev build $tag"
gh release delete "$tag" --repo "$GITHUB_REPOSITORY" --yes --cleanup-tag || true
done
# The tarball job above proves the *source* packaging. This one proves the
# *image* packaging, which is a different artifact with a different file list
# -- and the one that shipped issue #101 (the panel serves scripts/install.sh
# off its own disk; the Dockerfile never copied it, so every containerised
# panel 404'd the enrollment URL its own UI prints). Booting the image is the
# only check that sees it: pytest runs against the source tree, where the file
# is always present.
docker-image-smoke:
name: Boot the Docker image
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build image (amd64)
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64
push: false
load: true
tags: serverkit:smoke
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Smoke test the built image
run: SKIP_BUILD=1 bash scripts/test/smoke-docker-image.sh serverkit:smoke