feat: live tracker suite - WIKITOOL_TASKS_CONFIG override, real-tracker tests for Super Productivity and CalDAV, nightly workflow and test image (#156)
Files changed: - .gitea/scripts/start-radicale.sh - .gitea/sp-live/Dockerfile - .gitea/sp-live/resolve-version.sh - .gitea/workflows/ci.yml - .gitea/workflows/sp-live-image.yml - .gitea/workflows/tracker-live.yml - .gitignore - CHANGES.md - DEVELOPMENT.md - INSTALL.md - VERSION - instructions/dev/doc-pull-through.md - instructions/dev/stack-dev/SKILL.md - instructions/dev/testing-conventions.md - instructions/dev/tracker-testing.md - kb/gtd/INDEX.md - kb/gtd/technik/Chemenu 8.0.0 freigeben.md - kb/gtd/technik/Windows nativ unterstützen.md - kb/index.md - tools/CONTRACT.md - tools/chemenu/commands/docs_verify.py - tools/chemenu/commands/doctor.py - tools/chemenu/commands/review_cmd.py - tools/chemenu/commands/task_cmd.py - tools/chemenu/config.py - tools/chemenu/tasks/config.py - tools/chemenu/tests/conftest.py - tools/chemenu/tests/fixtures/sp/MANIFEST.json - tools/chemenu/tests/fixtures/sp/api/health.json - tools/chemenu/tests/fixtures/sp/api/projects.json - tools/chemenu/tests/fixtures/sp/api/tags.json - tools/chemenu/tests/fixtures/sp/api/tasks.json - tools/chemenu/tests/fixtures/sp/seed-backup.json - tools/chemenu/tests/record_sp_fixtures.py - tools/chemenu/tests/sp_headless.py - tools/chemenu/tests/test_doctor.py - tools/chemenu/tests/test_review.py - tools/chemenu/tests/test_sp_recorded.py - tools/chemenu/tests/test_task_cmd.py - tools/chemenu/tests/test_tasks_config.py - tools/chemenu/tests/test_tracker_live.py - tools/chemenu/tests/tracker_live.py - tools/pytest.ini
This commit is contained in:
1 parent
529793b255
commit
b0c64772cc
43 files changed
+2279
-32
No files matched your search
@@ -132,6 +132,21 @@ jobs:
|
||||
.venv/bin/python -m pytest -q \
|
||||
--cov --cov-report=term --cov-report=xml --cov-report=html
|
||||
|
||||
- name: Live tracker suite (CalDAV)
|
||||
# The one live tracker that needs no app and no display: a throwaway Radicale on
|
||||
# loopback. `CHEMENU_LIVE_REQUIRE=caldav` turns "no server" into a failure - without
|
||||
# it the suite would skip and stay green, which is exactly the outcome this step
|
||||
# exists to rule out (Gitea #156). The Super Productivity half is nightly, in
|
||||
# `tracker-live.yml`; see instructions/dev/tracker-testing.md.
|
||||
env:
|
||||
CHEMENU_LIVE_REQUIRE: caldav
|
||||
run: |
|
||||
set -eu
|
||||
tools/.venv/bin/pip install --quiet radicale
|
||||
.gitea/scripts/start-radicale.sh tools/.venv/bin/python /tmp/radicale
|
||||
cd tools
|
||||
.venv/bin/python -m pytest -q -m live_tracker -k caldav -s
|
||||
|
||||
- name: Coverage report
|
||||
# `always()`: a red suite is exactly when the per-module numbers are
|
||||
# worth reading, and the upload must not disappear with the failure.
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
# Builds the image the nightly `tracker-live` run executes in: Debian, the packaged Super
|
||||
# Productivity, a virtual display and the tools the suite needs (Gitea #156). It lives in
|
||||
# this Gitea instance's registry as `gitea.nehmer.net/torben/chemenu-sp-live`.
|
||||
#
|
||||
# The image follows the update channel, not a pin. Installed desktop apps update themselves,
|
||||
# so a pinned old version would be tested while users already run the new one. Every day this
|
||||
# workflow asks `latest-linux.yml` (`.gitea/sp-live/resolve-version.sh`) which release is
|
||||
# current, and builds only when the registry does not hold that tag yet. It also rebuilds once
|
||||
# a month regardless, so the Debian layers behind the app do not age unnoticed.
|
||||
#
|
||||
# Tags: `:<sp-version>` always, `:latest` only when that version is what the channel says.
|
||||
# A manual run with `sp_version` builds an older release (to reproduce a red night against
|
||||
# the version it went red on) and therefore never moves `:latest`.
|
||||
#
|
||||
# Runner shape follows torben/gitea-mcp, `.gitea/workflows/binford-release.yaml`: the
|
||||
# `container-builder` label, a remote BuildKit on the runner host, and the registry login from
|
||||
# 1Password. `OP_SERVICE_ACCOUNT_TOKEN` is a user-level secret that covers `torben/*`.
|
||||
#
|
||||
# After the very first push the package has to be linked to this repository once, by hand, in
|
||||
# the Gitea UI - a step no workflow can do. Until then the image builds and pulls fine; only
|
||||
# the package page shows no repository.
|
||||
|
||||
name: SP live image
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# 04:10 UTC, an hour after `nightly` and well before `tracker-live` (05:00), so a new
|
||||
# release is in the registry by the time the suite looks for it.
|
||||
- cron: '10 4 * * *'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
sp_version:
|
||||
description: 'Super Productivity release to build (default: the current one)'
|
||||
required: false
|
||||
force:
|
||||
description: 'Rebuild even if the tag already exists (true/false)'
|
||||
required: false
|
||||
default: 'false'
|
||||
|
||||
env:
|
||||
REGISTRY: gitea.nehmer.net/torben
|
||||
IMAGE_NAME: chemenu-sp-live
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: container-builder
|
||||
container:
|
||||
image: debian:trixie-slim
|
||||
steps:
|
||||
- name: Install CI dependencies
|
||||
# `nodejs` is for act_runner's JavaScript actions, not for us - see ci.yml.
|
||||
run: |
|
||||
set -eu
|
||||
apt-get update -qq
|
||||
apt-get install -y --no-install-recommends \
|
||||
git nodejs curl docker-cli docker-buildx ca-certificates iproute2 gawk
|
||||
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Resolve the Super Productivity release
|
||||
id: sp
|
||||
env:
|
||||
REQUESTED: ${{ inputs.sp_version }}
|
||||
run: |
|
||||
set -eu
|
||||
channel="$(.gitea/sp-live/resolve-version.sh latest)"
|
||||
channel_version="$(printf '%s\n' "$channel" | sed -n 's/^version=//p')"
|
||||
if [ -n "${REQUESTED:-}" ]; then
|
||||
wanted="$(.gitea/sp-live/resolve-version.sh "$REQUESTED")"
|
||||
else
|
||||
wanted="$channel"
|
||||
fi
|
||||
{
|
||||
printf '%s\n' "$wanted"
|
||||
echo "channel_version=$channel_version"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
printf '%s\n' "$wanted"
|
||||
|
||||
- name: Load secrets from 1Password
|
||||
uses: 1password/load-secrets-action@v2
|
||||
with:
|
||||
export-env: true
|
||||
env:
|
||||
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
|
||||
REGISTRY_USER: op://CI-CD/gitea-package-token/username
|
||||
REGISTRY_PAT: op://CI-CD/gitea-package-token/password
|
||||
|
||||
- name: BuildKit setup (remote builder)
|
||||
run: |
|
||||
HOST_IP=$(ip route | awk '/default/ { print $3 }')
|
||||
docker buildx create --name remote-builder --driver remote tcp://$HOST_IP:1234 --use --bootstrap
|
||||
|
||||
- name: Log in to the container registry
|
||||
run: |
|
||||
echo "$REGISTRY_PAT" | docker login gitea.nehmer.net -u "$REGISTRY_USER" --password-stdin
|
||||
|
||||
- name: Decide whether to build
|
||||
id: decide
|
||||
env:
|
||||
SP_VERSION: ${{ steps.sp.outputs.version }}
|
||||
CHANNEL_VERSION: ${{ steps.sp.outputs.channel_version }}
|
||||
FORCE: ${{ inputs.force }}
|
||||
run: |
|
||||
set -eu
|
||||
ref="$REGISTRY/$IMAGE_NAME:$SP_VERSION"
|
||||
build=false
|
||||
why=""
|
||||
if [ "${FORCE:-false}" = true ]; then
|
||||
build=true; why="forced"
|
||||
elif [ "$(date -u +%d)" = 01 ]; then
|
||||
build=true; why="monthly rebuild"
|
||||
elif ! docker buildx imagetools inspect "$ref" > /dev/null 2>&1; then
|
||||
build=true; why="$ref is not in the registry yet"
|
||||
fi
|
||||
tags="$ref"
|
||||
if [ "$SP_VERSION" = "$CHANNEL_VERSION" ]; then
|
||||
tags="$tags
|
||||
$REGISTRY/$IMAGE_NAME:latest"
|
||||
fi
|
||||
{
|
||||
echo "build=$build"
|
||||
echo "tags<<EOF"
|
||||
echo "$tags"
|
||||
echo "EOF"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
echo "build=$build ${why:+($why)}; tags: $tags"
|
||||
|
||||
- name: Build and push
|
||||
if: steps.decide.outputs.build == 'true'
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .gitea/sp-live
|
||||
file: .gitea/sp-live/Dockerfile
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
tags: ${{ steps.decide.outputs.tags }}
|
||||
build-args: |
|
||||
SP_VERSION=${{ steps.sp.outputs.version }}
|
||||
SP_SHA512=${{ steps.sp.outputs.sha512 }}
|
||||
@@ -0,0 +1,69 @@
|
||||
# The live tracker suite, nightly (Gitea #156): the documented `task` and `review` workflow
|
||||
# against a real Super Productivity and a real CalDAV server, not against fakes.
|
||||
#
|
||||
# `ci.yml` already runs the CalDAV half on every push (Radicale is a pip install). This
|
||||
# workflow adds the half that needs the desktop app, inside the prebuilt
|
||||
# `chemenu-sp-live` image (`sp-live-image.yml`), and runs both, so one green night covers both
|
||||
# providers.
|
||||
#
|
||||
# Red after a new Super Productivity release is the finding this workflow exists for, not a
|
||||
# flaky night: `instructions/dev/tracker-testing.md` says what to do with it. An agent that
|
||||
# touched the Super Productivity surface (`tasks/superproductivity.py`, `tasks/config.py`,
|
||||
# the fixtures) dispatches it by hand instead of waiting for the clock.
|
||||
#
|
||||
# Runner: `linux-docker`, with the image as the job container. The image carries `nodejs`, so
|
||||
# `actions/checkout` runs; see ci.yml for why that is the workflow's business.
|
||||
|
||||
name: Tracker live
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 5 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
live:
|
||||
runs-on: linux-docker
|
||||
container:
|
||||
image: gitea.nehmer.net/torben/chemenu-sp-live:latest
|
||||
env:
|
||||
WIKITOOL_SESSION_ID: tracker-live-${{ github.run_id }}
|
||||
WIKI_TRACE_DIR: /tmp/wikitool-trace
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Which Super Productivity is this
|
||||
# The image tag says which release it was built for; whether `:latest` was pulled
|
||||
# fresh or served from the runner's cache is not certain. So the run compares what is
|
||||
# installed with what the update channel names now, and says so in the log.
|
||||
run: |
|
||||
set -eu
|
||||
installed="$(dpkg-query -W -f='${Version}' superproductivity)"
|
||||
channel="$(.gitea/sp-live/resolve-version.sh latest | sed -n 's/^version=//p')"
|
||||
echo "installed: $installed, update channel: $channel"
|
||||
if [ "$installed" != "$channel" ]; then
|
||||
echo "::warning::the image carries Super Productivity $installed, the update channel names $channel - this run tests an outdated app (stale runner cache or an image not rebuilt yet)"
|
||||
fi
|
||||
|
||||
- name: Tool environment
|
||||
run: |
|
||||
set -eu
|
||||
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
python3 -m venv tools/.venv
|
||||
tools/.venv/bin/pip install --quiet --upgrade pip
|
||||
tools/.venv/bin/pip install --quiet -r tools/requirements.txt
|
||||
tools/.venv/bin/pip install --quiet pytest radicale
|
||||
|
||||
- name: Start Radicale
|
||||
run: .gitea/scripts/start-radicale.sh tools/.venv/bin/python /tmp/radicale
|
||||
|
||||
- name: Live tracker suite
|
||||
# Both kinds are required: a night in which the app or the server was not there must
|
||||
# fail rather than skip.
|
||||
env:
|
||||
CHEMENU_LIVE_REQUIRE: sp,caldav
|
||||
run: |
|
||||
set -eu
|
||||
cd tools
|
||||
.venv/bin/python -m pytest -q -m live_tracker -s
|
||||
Reference in new issue
Block a user