Skip to content

CI and releases

What Where
ISO downloads SourceForge Files: https://sourceforge.net/projects/flickos/files/ (one folder per release, e.g. v2.0/)
Apt repository GitHub Pages (dvbondoy/flickos-apt): https://dvbondoy.github.io/flickos-apt/ (05)
Source code, CI, issues GitHub: https://github.com/Flick-OS/flickos
Website https://flickos.net

Release history: FlickOS 1.0 and 1.1 (FlickOS-64bit-v1.1.iso, May 2023) were based on Ubuntu 20.04 and LXLE. FlickOS 2.0 is a rebuild on Debian 13. There is no in-place upgrade from 1.x to 2.0. Release notes must tell 1.x users to back up their files and reinstall.

FLICKOS_VERSION in packages/flickos-branding/usr/lib/flickos-release is the single source of the FlickOS version:

Uses it How
ISO file name tools/build-iso.sh names the ISO FlickOS-64bit-v2.0.iso
ISO volume label auto/config reads it for --iso-volume "FlickOS 2.0 amd64"
/etc/os-release, /etc/issue Generated by flickos-branding (09)
SourceForge folder tools/upload-release.sh uploads to files/v2.0/
Git tag CI refuses a tag that isn’t v + FLICKOS_VERSION
Boot test Check FlickOS version matches build

One copy can’t read that file: the installer’s packages/flickos-installer/etc/calamares/branding/flickos/branding.desc (version, shortVersion, versionedName, shortVersionedName). tools/build-iso.sh stops with Version mismatch if you forget to update it.

GitHub Actions builds the ISO on a clean machine so builds don’t depend on your laptop.

Trigger Result
Push to main ISO built and boot-tested, uploaded as a workflow artifact (kept 7 days)
Pull request Same. Checks the change doesn’t break the build or the boot
Only repo/community/apps/ changed (push or pull request) Nothing: a community app is no part of the ISO (paths-ignore; community.yml below builds it)
Manual (Actions tab → Build ISO → Run workflow) Same
Push a tag vX.Y (e.g. v2.0) Same, plus upload of the ISO and SHA256SUMS to SourceForge, and a GitHub Release with SHA256SUMS and a download link
  1. Starts a privileged debian:trixie container. live-build needs root, mount and chroot, and must match the target release.
  2. Installs the build tools (live-build, debhelper, …, and sfwbar’s Build-Depends), the test tools (qemu-system-x86, xorriso, python3) and the upload tools (rsync, openssh-client). wget is listed explicitly because live-build’s firmware step needs it and --no-install-recommends would skip it.
  3. Checks out the repo.
  4. On tags only: checks the tag equals v + FLICKOS_VERSION.
  5. tools/build-iso.sh --purge: builds the FlickOS packages from the commit being tested, then FlickOS-64bit-vX.Y.iso and SHA256SUMS. It’s the same script you run locally.
  6. tools/boot-test.py: boots the ISO headless and runs the checks. See 02. A failed check fails the workflow and shows as an error annotation on the run.
  7. Uploads the boot-test artifact (serial.log, screen.png, build.log), even when an earlier step failed, so you can see why.
  8. Uploads the flickos-iso artifact (ISO + SHA256SUMS).
  9. On tags only, if the SourceForge secrets are set: tools/upload-release.sh uploads the ISO and SHA256SUMS to sourceforge.net/projects/flickos/files/vX.Y/.
  10. On tags only: creates a GitHub Release with SHA256SUMS and a link to the SourceForge folder. The ISO itself isn’t attached, because GitHub release files are limited to 2 GB and FlickOS with LibreOffice can exceed that.

A tag is only uploaded and released if the build and boot test passed, because later steps don’t run after a failure. permissions: contents: write at the top allows step 10.

KVM in CI: the privileged container can use the runner’s /dev/kvm, so the boot test normally runs accelerated. If KVM isn’t available, the test prints a warning annotation and runs much slower, with longer timeouts.

One-time setup: SourceForge upload secrets

Section titled “One-time setup: SourceForge upload secrets”
  1. Create an SSH key only for CI (no passphrase): ssh-keygen -t ed25519 -N '' -C flickos-ci -f flickos-ci
  2. Add flickos-ci.pub to the SourceForge account that uploads, at https://sourceforge.net/auth/shell_services. That account must be allowed to release files in the flickos project.
  3. In GitHub → repo Settings → Secrets and variables → Actions → New repository secret:
    • SF_USER: the SourceForge username, e.g. dvbondoy
    • SF_SSH_PRIVATE_KEY: the full content of the flickos-ci file
  4. Delete the local flickos-ci private key file. If it leaks, remove the public key on SourceForge and repeat.

Without these secrets, tagged builds still work but skip the SourceForge upload. Upload by hand with tools/upload-release.sh instead.

  • The public key packages/flickos-archive-keyring/keyrings/flickos-archive-keyring.asc is committed.
  • The apt repository is published at the address in packages/flickos-archive-keyring/etc/apt/sources.list.d/flickos.sources (https://dvbondoy.github.io/flickos-apt). The build’s final apt update needs it (05).
  • The version in branding.desc matches flickos-release.
  • All scripts and hooks are committed with the executable bit. Check with git ls-files -s packages/*/debian/rules packages/*/debian/*.post* config/hooks auto repo/*.sh tools. Mode 100755 = executable, 100644 = not. Fix with git update-index --chmod=+x FILE.

The secret signing key is not needed in CI. CI only builds and uploads the ISO, it doesn’t publish the apt repository.

Getting the ISO and test results from a run

Section titled “Getting the ISO and test results from a run”

GitHub → your repo → Actions → click the run → Artifacts:

  • flickos-iso: zip containing the ISO and SHA256SUMS
  • boot-test: boot-test/serial.log, boot-test/screen.png and build.log

When the boot test fails, open serial.log first. It shows how far the boot got and the output of the failing check.

  • Build time is roughly 30–50 minutes, plus a few minutes for the boot test. Jobs time out after 6 hours.
  • Artifact storage counts against your GitHub quota. That’s why retention is 7 days.
  • Runner disk space is about 14 GB free. If builds fail with No space left on device, remove preinstalled tools in an extra first step, or build locally.

Community apps: .github/workflows/community.yml

Section titled “Community apps: .github/workflows/community.yml”

Builds other developers’ apps for the community repository (Software design, ADR-004; repo/community/README.md). It runs on pushes to main and pull requests that touch repo/community/, flickos-archive-keyring or the workflow, and by hand.

  1. changed (a debian:trixie container): runs the checks’ own tests (repo/community/tests/), then build.py --changed BASE lists the apps whose file was added or changed (the pull request’s base, or the push’s previous commit; by hand: every app).
  2. build, one job per app (a matrix): adds FlickOS’s two distributions from flickos-archive-keyring (the checks ask apt where a dependency comes from), creates the user builder and blocks its network with iptables (the job’s container has NET_ADMIN for that, in its own network namespace only), then build.py --install-build-deps --build-user builder --base BASE NAME: clone, refuse a tag that doesn’t point at the listed commit and source that can’t be reviewed, install the build dependencies, build that commit as builder (offline; build.py stops if it isn’t), run check.py (lintian included), write the source diff since the published commit and review.txt, the lines to look at. The summary goes on the run’s page; the folder (.deb, check.txt, source.diff, summary.md) becomes the artifact community-NAME-COMMIT (90 days), or failed-NAME when it failed.

The workflow has no secrets and a read-only token: building runs the developer’s debian/rules. Nothing is signed here; the maintainer’s repo/community/publish.sh takes only artifacts of runs on main, since a pull request runs its own copy of the workflow.

Discord notices: .github/workflows/discord.yml

Section titled “Discord notices: .github/workflows/discord.yml”

Every push to main posts its commits’ first lines to a Discord channel, and every v* tag posts a notice with the release’s address (the release itself appears only once iso.yml passes). Other branches and pull requests post nothing. Commit messages become public there, so keep them fit to be read.

One-time setup: in Discord, Channel settings → Integrations → Webhooks → New Webhook, copy its URL, and add it in GitHub as the repository secret DISCORD_WEBHOOK. Without it the workflow posts nothing. Anyone with the URL can post to the channel: if it leaks, delete the webhook and make a new one.

To post commits from before the workflow existed, run tools/discord-post-commits.py with git log arguments, for example DISCORD_WEBHOOK=URL tools/discord-post-commits.py -n 20 main (or --webhook-file FILE). --dry-run prints the messages instead.

Use this for every FlickOS release. The examples use 2.0.

Prepare

  • All package changes have bumped versions (dch -i -D trixie) and are committed.
  • Shortcut for the next three items: tools/release.sh 2.0 does the version bump and the repo publish below, then waits for the new InRelease to be online (--no-publish stops after the bump). It commits nothing; run it again with the same version to resume after a failed publish. By hand:
  • Set the FlickOS version and commit:
    • FLICKOS_VERSION="2.0" in packages/flickos-branding/usr/lib/flickos-release, then bump that package (dch -i -D trixie "FlickOS 2.0.").
    • The four version strings in packages/flickos-installer/etc/calamares/branding/flickos/branding.desc, then bump that package.
  • repo/publish.sh && repo/upload.sh, then check with curl -fsSI https://dvbondoy.github.io/flickos-apt/dists/trixie/InRelease.
  • Write release notes (what’s new, known issues, and for 2.0: reinstall required when coming from 1.x).

Build and test locally (see 02)

  • tools/build-iso.sh --purge → FlickOS-64bit-v2.0.iso
  • tools/boot-test.py --strict passes.
  • tools/test-iso.sh --bios and tools/test-iso.sh --uefi: boot menu works, desktop works.
  • tools/test-iso.sh --reset --install: install with Calamares, reboot, log in, labwc starts. The first install slide mentions the weekly count; flickos-countme status shows it on (and, with URL set, a last_week after sudo systemctl start flickos-countme).
  • tools/test-iso.sh --disk: sudo apt update && sudo apt upgrade works with no errors.

Publish

  • git push, and wait for CI on main to pass.
  • Tag and push:
    Terminal window
    git tag -a v2.0 -m "FlickOS 2.0"
    git push origin v2.0
  • Wait for the workflow. Without CI secrets, upload by hand: tools/upload-release.sh.
  • On SourceForge → Files → v2.0:
    • upload the release notes as README.md in that folder (SourceForge shows it below the file list),
    • click ⓘ next to FlickOS-64bit-v2.0.iso → Default Download For: select all → Save, so the big green Download button offers the new release.
  • Update the project summary/description on SourceForge if the base or features changed (for 2.0: Debian 13, labwc).
  • On GitHub → Releases → v2.0: paste the release notes.
  • Download the ISO from SourceForge and verify it: sha256sum -c SHA256SUMS.
  • Announce on r/flickos.

If a release is broken: delete the GitHub Release and the tag (git push --delete origin v2.0, git tag -d v2.0). On SourceForge, hide or delete the files in v2.0/ and restore the previous default download. Fix, set FLICKOS_VERSION="2.0.1" and release v2.0.1. Don’t reuse a version people may already have downloaded.

They’re independent:

  • FlickOS release (FLICKOS_VERSION, tag v2.0, ISO name): the ISO snapshot as a whole.
  • Package versions (flickos-settings 1.3): bumped whenever that package changes. Many package updates can ship between two ISO releases, through the apt repo.
  • A second workflow that publishes the apt repository when files in packages/ change. It needs the secret signing key as an encrypted GitHub secret.
  • Cache cache/ between CI runs with actions/cache to speed up builds.