.github/workflows/ci.yml
name: CI
# Runs full Plasma coverage except for proven editorial-only PR/main changes; on version tags
# (`vX.Y.Z`) additionally builds the `.plasmoid` and publishes a GitHub Release.
#
# Runtime checks and smoke tests use the prebuilt Ubuntu/Neon CI image.
on:
push:
branches: [main]
tags: ['v*']
pull_request:
workflow_dispatch:
schedule:
- cron: '23 7 * * 1'
# Only superseded PR runs are cancelled. Each main push and release keeps its run.
concurrency:
group: ci-${{ github.event.pull_request.number || github.run_id }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
permissions:
contents: read
env:
DEBIAN_FRONTEND: noninteractive
LANG: C.UTF-8
# Explicit import warnings prevent the local missing-module fallback.
QMLLINT_FLAGS: --import warning --unqualified disable
QML_TEST_REQUIRE_NO_SKIPS: '1'
jobs:
lint:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install lightweight check tooling
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
make shellcheck jq libxml2-utils python3-pyflakes curl ca-certificates gettext zip
sudo bash scripts/install-actionlint.sh
- name: Run fast checks
run: |
command -v actionlint
python3 -c 'import pyflakes'
make check-shellcheck check-workflows check-python-lint check-changelog \
check-python-test_documentation check-python-test_ci_scope check-config-schema check-metadata
make package
scope:
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
run_runtime: ${{ steps.scope.outputs.run_runtime }}
steps:
- name: Checkout comparison history
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
fetch-depth: 0
- name: Select Plasma coverage
id: scope
run: python3 scripts/ci_scope.py
check-runtime:
needs: scope
if: needs.scope.outputs.run_runtime == 'true'
runs-on: ubuntu-latest
timeout-minutes: 20
container:
image: ghcr.io/lucenx9/codexbar-plasma-ci-runtime@sha256:581a1870084038e88c12808e1cac44dee715259567de11abe67eb3d4e9694b14
credentials:
username: ${{ github.actor }}
password: ${{ github.token }}
options: --user 0
permissions:
contents: read
packages: read
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Verify image matches its checked-in recipe
run: sha256sum --check --strict /usr/local/share/ci-inputs.sha256
- name: make check
run: make check
- name: make package
run: make package
smoke-runtime:
needs: scope
if: needs.scope.outputs.run_runtime == 'true'
runs-on: ubuntu-latest
timeout-minutes: 20
container:
image: ghcr.io/lucenx9/codexbar-plasma-ci-runtime@sha256:581a1870084038e88c12808e1cac44dee715259567de11abe67eb3d4e9694b14
credentials:
username: ${{ github.actor }}
password: ${{ github.token }}
options: --user 0
permissions:
contents: read
packages: read
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Verify image matches its checked-in recipe
run: sha256sum --check --strict /usr/local/share/ci-inputs.sha256
- name: Exercise the popup on a virtual display
run: xvfb-run -a -s '-screen 0 1280x1024x24' make smoke SMOKE_ARGS='--output dist/smoke/ci'
- name: Upload popup screenshots and logs
if: always()
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: popup-smoke
path: dist/smoke/ci
if-no-files-found: warn
retention-days: 7
- name: Capture panel content combinations with OpenGL
run: xvfb-run -a -s '-screen 0 1280x1024x24' python3 scripts/panel_matrix.py --output dist/smoke/panel-matrix
- name: Upload panel matrix gallery and measurements
if: always()
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: panel-matrix
path: dist/smoke/panel-matrix
if-no-files-found: warn
retention-days: 7
check:
if: always()
needs: [scope, lint, check-runtime]
permissions:
contents: read
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout coverage validator
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Report required check result
env:
SCOPE_RESULT: ${{ needs.scope.result }}
RUN_RUNTIME: ${{ needs.scope.outputs.run_runtime }}
RUNTIME_RESULT: ${{ needs.check-runtime.result }}
LINT_RESULT: ${{ needs.lint.result }}
run: python3 scripts/ci_scope.py --gate check
smoke:
if: always()
needs: [scope, smoke-runtime]
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout smoke result validator
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Report required smoke result
env:
SCOPE_RESULT: ${{ needs.scope.result }}
RUN_RUNTIME: ${{ needs.scope.outputs.run_runtime }}
RUNTIME_RESULT: ${{ needs.smoke-runtime.result }}
run: python3 scripts/ci_scope.py --gate smoke
release:
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
needs: [check, smoke]
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: write
steps:
- name: Install build-only tooling
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
make git ca-certificates jq gettext python3 zip
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Verify release tag matches metadata
shell: bash
run: |
if [[ ! "$GITHUB_REF_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "release tag must use vX.Y.Z: $GITHUB_REF_NAME" >&2
exit 1
fi
metadata_version="$(jq -r '.KPlugin.Version // empty' metadata.json)"
if [[ -z "$metadata_version" || "v${metadata_version}" != "$GITHUB_REF_NAME" ]]; then
echo "release tag $GITHUB_REF_NAME does not match metadata version $metadata_version" >&2
exit 1
fi
- name: Prepare release notes from changelog
shell: bash
run: |
mkdir -p dist
python3 scripts/changelog.py --tag "$GITHUB_REF_NAME" > dist/release-notes.md
- name: make package
run: make package
- name: Publish release
# v3.0.2 creates a draft, uploads every asset, and only then publishes.
# Keep repository release immutability enabled so the updater can trust
# the published tag and asset digests.
uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3
with:
files: |
dist/codexbar-plasma.plasmoid
dist/codexbar-plasma.plasmoid.sha256
body_path: dist/release-notes.md
generate_release_notes: false