Commit Graph
410 Commits
Author SHA1 Message Date
kevinveenbirkenbach 8563df9400 chore: adopt git-maintainer-tools as dev dependency for git ops
Drop the project-local copy of scripts/git/sign-push.sh in favour of
the git-maintainer-tools CLIs (git-setup-remotes, git-sign-push),
which now ship as a standalone PyPI/GitHub package so the same helpers
can be reused across every maintainer repo without vendoring shell
scripts.

The package is declared in pyproject.toml's `dev` extras and lands on
$PATH via `make install-python-dev` (which already runs
`pip install -e .[dev]`). Consumers invoke the CLIs directly; there
are no make wrappers because doing so would just duplicate help text
the tool itself already prints.

Fallout:
  * scripts/git/sign-push.sh deleted.
  * Makefile: sign-push target removed (no replacement target).
  * .claude/settings.json: deny rule for `make sign-push*` replaced
    with direct `git-setup-remotes*` / `git-sign-push*` denies so the
    sandbox blocks the real binaries, not just the make alias.
  * CLAUDE.md: operator instruction points at the bare `git-sign-push`
    CLI + `make install-python-dev` for setup.
  * docs/contributing/artefact/git/remotes.md: new tool-focused page.
    Describes the layout and the two CLIs; does not duplicate raw git
    commands already covered by git-maintainer-tools.
  * docs/contributing/artefact/git/README.md: trimmed per readme_md.md
    (docs READMEs must not act as a file index).
  * docs/contributing/tools/make.md: Git section now documents the
    external CLIs and the install entry point, not a wrapper target.
2026-04-25 09:38:26 +02:00
kevinveenbirkenbach d5e9ad072b docs: relocate guides/ to administration/
Move installation.md and rename administration.md to deploy.md under
docs/administration/, delete docs/guides/, and add a scope-only
README.md per the docs-README rules. Update README.md, SUPPORT.md,
and scripts/tests/environment/README.md cross-links.

Refresh roles/web-app-decidim/README.md to match the current OIDC
patch set (decidim-core omniauth.rb + omniauth_helper.rb only, no
secrets.yml on Rails 7.2, ENV-prefixed credential names).
2026-04-21 21:04:03 +02:00
kevinveenbirkenbachandClaude Opus 4.7 8ce9179706 fix(lookups,web-app-peertube): finish users/applications migration and harden OIDC plugin install
- Resolve merge conflict in web-app-peertube/vars/main.yml; migrate
  remaining `applications |` and `users.*` references to
  `lookup('applications')` / `lookup('users', ...)` in web-app-odoo and
  web-app-decidim (compose, env, playwright, setup tasks).
- web-app-peertube: split OIDC tasks into oidc/{enable,disable}.yml,
  add install_mem_limit filter + PEERTUBE_MEM_LIMIT /
  PEERTUBE_OIDC_PLUGIN_INSTALL_MEM_LIMIT vars to raise the cgroup ceiling
  during the one-off `npm run plugin:install` exec (prevents OOM-SIGKILL
  that was surfacing as "Container is restarting"); add
  upsert-oidc-plugin.sql.j2 and diagnostics.sh.
- CI: test-deploy-{local,server,universal,workstation}.yml tweaks plus
  scripts/github/{dump_runner_state,enlarge_swap}.sh for constrained
  runners.
- cli/meta/applications/ressources: new CLI entry with unit tests.
- Misc config/docs updates across dashboard, mailu, mattermost, asset,
  cdn, file roles and contributing docs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 10:14:21 +02:00
kevinveenbirkenbach cc5d4e6d54 Merge pull request #182 from kevinveenbirkenbach/fix/web-app-peertube/oom/162
Fix peertube OOM during auth-openid-connect plugin install (#162)
2026-04-21 09:05:31 +02:00
kevinveenbirkenbach 17b6d755fd Merge branch 'main' into fix/users-applications.yml
Resolve conflicts by migrating lookup plugins to utils.applications.config
(get_app_conf -> get) while preserving branch's runtime applications/users
lookups. Notable changes:

- plugins/lookup/{config,nginx,service}.py, roles/web-app-dashboard/
  lookup_plugins/docker_cards.py: switch to utils.applications.config.get,
  keep utils.runtime_lookup_data.get_merged_applications/_users.
- roles/web-app-matrix/docs/Installation.md: use lookup('config', ...)
  syntax with markdown link formatting.
- scripts/tests/e2e/rerun-spec.sh: take main's single-source image tag
  derivation from roles/test-e2e-playwright/defaults/main.yml.
- tests/integration/test_get_app_conf_paths.py -> test_config_lookup_paths.py:
  migrate scan pattern to lookup('config', ...) and skip docs/ directory.
- tests/unit/plugins/lookup/test_config_lookup.py: union of new imports.
- tests/unit/plugins/lookup/test_cert.py: reset runtime caches in
  setUp/tearDown to avoid id()-based fingerprint cross-test pollution.
- Add __init__.py in 7 test directories left behind after prior cleanup.
- Delete dead duplicate group_vars/all/{04_users,05_applications}.yml
  (untracked on disk; content long migrated to roles/*/{config,users}/main.yml).
2026-04-21 02:34:06 +02:00
kevinveenbirkenbachandClaude Opus 4.7 fe18ae43cf Fix enlarge_swap.sh starving deploys of disk space (#162)
Swap size was free(/)-25, which took ~99 GB on the 145 GB root fs.
Remaining ~25 GB then ran out mid-deploy during Playwright image
pulls (ENOSPC). Replace with a fixed 16 GB cap and use mountpoint
to detect a real /mnt partition instead of [ -d /mnt ], which
matched the empty placeholder dir on single-partition runners.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-20 16:54:03 +02:00
kevinveenbirkenbach 5e02e084dc Merge branch 'main' into feature/e2e-friendica-joomla-playwright 2026-04-20 16:29:56 +02:00
kevinveenbirkenbachandClaude Opus 4.7 033b045cf0 Add nested-container diagnostics to runner-state dump
Surfaces df, failed units, and hlth-disc-space status/journal from
inside the infinito container so failure-time dumps reflect the same
filesystem view that the disk-space health check evaluates, not just
the host.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-20 12:44:37 +02:00
kevinveenbirkenbachandClaude Opus 4.7 6fac8996ff Add runner-state diagnostic helper for CI deploy debugging
Extracts disk/memory/docker/swap dump into a reusable helper,
calls it pre/post swap resize, and runs it on deploy failure
across all four deploy workflows. Also adds SKIP_SWAP=1
short-circuit for A/B probing swap-related regressions.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-20 12:37:54 +02:00
kevinveenbirkenbachandClaude Opus 4.7 0cfe0b4d51 Normalize whitespace in enlarge_swap.sh
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-20 03:23:37 +02:00
kevinveenbirkenbachandClaude Opus 4.7 8cdfcad9ef Enlarge CI runner swap dynamically across deploy workflows
Introduce scripts/github/enlarge_swap.sh that consumes all remaining
space on / minus a 25 GB buffer (Docker layers, checkout, runtime
state), falling back to /mnt when / is too small. Replaces the
default ~4 GB runner swap so transient memory spikes (e.g. peertube
plugin install, issue #162) don't trip the host OOM-killer on the
16 GB GitHub-hosted runner.

Wire the script into all four deploy test workflows (local, universal,
server, workstation) and flip free-disk-space to the aggressive config
(tool-cache, large-packages, docker-images, swap-storage all true):
the deploy actually runs inside the infinito container, so host-side
toolchains, language runtimes, and the default Docker layer cache are
dead weight. Update the workflow SPOT doc accordingly.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-20 03:18:45 +02:00
kevinveenbirkenbach b5c4b8a3d9 Merge branch 'main' into fix/users-applications.yml 2026-04-19 22:21:16 +02:00
kevinveenbirkenbach 19de80b506 fix(sign-push): sign via rebase -S instead of exec amend
The --exec 'git commit --amend --allow-empty --no-edit -S' pattern
multiplied identical-tree empty commits during a rebase-merges run
(observed: 3 upstream empties became 16 locally). git rebase -S signs
every rewritten commit natively, without the amend loop, while still
preserving merges via --rebase-merges.
2026-04-19 22:16:44 +02:00
kevinveenbirkenbach eb5e87ee28 fix(sign-push): allow amending empty commits during re-sign
The re-sign rebase failed on empty commits pulled in from upstream
because git refused the --amend. Adding --allow-empty keeps those
commits in place while still GPG-signing them.
2026-04-19 22:04:24 +02:00
kevinveenbirkenbach c3da3ce013 fix(scripts): derive Playwright image tag from defaults/main.yml
The old derivation read @playwright/test out of
roles/test-e2e-playwright/files/package.json and assembled the tag
as `v{version}-{distro}`. That package.json no longer exists — the
version+distro tag now lives verbatim in defaults/main.yml under
images.playwright.version, so read it from the single source of
truth instead of rebuilding a broken tag from a missing file. The
TEST_E2E_PLAYWRIGHT_IMAGE_DISTRO fallback is no longer referenced
once the distro suffix is baked into the upstream version string.
2026-04-19 19:12:54 +02:00
kevinveenbirkenbach 2d91eb3368 Merge branch 'main' into fix/users-applications.yml 2026-04-19 15:37:37 +02:00
kevinveenbirkenbachandClaude Opus 4.7 5e75a4b0ad feat(git): add make sign-push and deny direct push in sandbox
Route pushes through scripts/git/sign-push.sh so the operator's GPG key
stays outside the sandbox. Script signs only @{u}..HEAD (or merge-base
with origin/main|master on first push), skips re-signing when all
commits already carry a good signature, and uses --force-with-lease on
rewritten history. settings.json denies git push*, git send-pack*, and
make sign-push* so the agent cannot trigger a push path directly.
CLAUDE.md instructs the agent to hand off to the operator instead.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 12:15:44 +02:00
kevinveenbirkenbach ccb3e8a96c Merge branch 'main' of github.com:infinito-nexus/core into fix/users-applications.yml 2026-04-19 03:29:31 +02:00
kevinveenbirkenbachandClaude Opus 4.7 9ffd118264 fix(skills): mirror .agents/skills to .claude/skills instead of symlink
The previous symlink approach left .claude/skills as a real empty dir in
some setups, which collides with the agent sandbox (denyWithinAllow on
.claude/skills expects a file path, not a directory) and breaks every
Bash invocation. Copy the installed skills tree into .claude/skills so
both locations are real, independent copies — no symlink involved.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-18 18:32:20 +02:00
kevinveenbirkenbach a8df31d898 Merge branch 'main' into fix/free-disk-space/138 2026-04-18 18:14:07 +02:00
kevinveenbirkenbachandClaude Opus 4.7 433a4138dd feat(ci): recognize chore branch prefix
Treat chore/** branches like feature/fix/etc. for CI: trigger the
push pipeline on chore/** pushes and accept chore as a valid PR
branch prefix in full scope. This unblocks the chore/update-* PRs
that update.yml creates automatically, which previously failed
branch-prefix validation and never triggered the push pipeline.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-18 17:11:28 +02:00
kevinveenbirkenbachandClaude Opus 4.7 4f2dd95fe9 feat(ci): add CI_RUN_ON_MAIN gate, reorg actions docs
Add repository variable CI_RUN_ON_MAIN that gates whether pushes to
main trigger CI. When unset (default), pushes to main skip CI;
set to 'true' to enable. Pushes to other branches are unaffected.

Reorganize GitHub Actions docs into a dedicated tools/github/actions/
directory and consolidate every CI repository variable in a single
SPOT (configuration.md). Move actions.md to actions/workflows.md and
branch/configuration.md to actions/configuration.md, then update
every cross-reference. Trim README files to scope-only per
docs/contributing/artefact/files/docs/readme_md.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-18 16:31:52 +02:00
kevinveenbirkenbachandClaude Opus 4.7 6364b8949f fix(install/arch): init pacman keyring before pacman -Syu
Move `pacman-key --init` + `--populate` ahead of the first `pacman -Syu`
call in `build_and_install_arch`. The previous guard
`pacman-key --list-sigs` always returned 0 on a fresh Manjaro/Arch image,
so the keyring init never ran and the upgrade of `archlinux-keyring`
failed with `==> ERROR: There is no secret key available to sign with.`,
breaking the manjarolinux/base test-environment matrix entry.

Refs: https://github.com/infinito-nexus/core/issues/167

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-18 12:28:35 +02:00
kevinveenbirkenbachandClaude Opus 4.7 fa10c3c9bc test(e2e): add playwright specs for keycloak, matomo, openwebui, discourse + extend dashboard
Closes Verification checkboxes in requirement 003. Each spec exercises
the `lookup('applications')` + `lookup('users')` pathway end-to-end:
login via lookup('users'), OIDC round-trip from dashboard (where the
app supports it), canonical-domain DOM assertion, and a full CSP
assertion covering every directive emitted by csp_filters.build_csp_header
(15 directives), meta-parity, enforced policy (not Report-Only), and
zero securitypolicyviolation events.

The dashboard spec is extended in place with the CSP + canonical-domain
assertions while keeping its existing login/logout coverage.

rerun-spec.sh is pointed at the Jinja template + the staged copy of
package.json (the repo has templates/package.json.j2, not files/package.json),
so the inner spec-only iteration loop works without re-deploying.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-17 08:53:47 +02:00
kevinveenbirkenbach 59173f7274 Merge branch 'main' into fix/users-applications.yml 2026-04-17 00:02:48 +02:00
kevinveenbirkenbach 4ee8441e33 Merge branch 'main' into fix/free-disk-space/138 2026-04-16 19:48:05 +02:00
Environment TestandClaude Opus 4.6 e2dbbceb6a chore(sandbox): add cross-distro installer for bwrap/socat via make agent-install
Adds scripts/install/sandbox.sh, a distro-aware installer for the OS-level
dependencies the Claude Code sandbox backend needs (bubblewrap, socat),
and exposes it through a new `make agent-install` target. Documents the
target in docs/contributing/tools/make.md, scripts/install/README.md, and
the Claude sandbox guide so contributors on a fresh host can bring up a
working sandbox without hand-installing distro packages.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 18:06:57 +02:00
Environment Test dfa8cd99bb Merge branch 'main' into fix/free-disk-space/138 2026-04-16 14:00:27 +02:00
kevinveenbirkenbach 34ddc4d2d2 Merge branch 'main' into fix/users-applications.yml
# Conflicts:
#	group_vars/all/00_general.yml
#	roles/web-app-dashboard/templates/playwright.env.j2
#	roles/web-app-nextcloud/config/main.yml
#	roles/web-app-nextcloud/templates/playwright.env.j2
2026-04-16 11:54:20 +02:00
kevinveenbirkenbach efc651a057 Merge branch 'main' of https://github.com/kevinveenbirkenbach/infinito-nexus-core 2026-04-16 11:31:31 +02:00
kevinveenbirkenbachandClaude Opus 4.6 f04bae680e chore(skills): symlink .claude/skills -> .agents/skills
Claude Code discovers project skills under .claude/skills/, but
`skills experimental_install` writes to .agents/skills/. Add a
relative symlink so installed skills (caveman, compress, ...) are
picked up without extra copy step.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 11:30:41 +02:00
kevinveenbirkenbachandClaude Opus 4.6 83d88a28fc chore(skills): symlink .claude/skills -> .agents/skills
Claude Code discovers project skills under .claude/skills/, but
`skills experimental_install` writes to .agents/skills/. Add a
relative symlink so installed skills (caveman, compress, ...) are
picked up without extra copy step.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 11:29:55 +02:00
kevinveenbirkenbach 262e1b43fc Merge branch 'main' into fix/users-applications.yml
# Conflicts:
#	docs/contributing/design/services.md
#	plugins/lookup/applications_current_play.py
#	plugins/lookup/service.py
#	roles/sys-stk-backend/lookup_plugins/service_should_load.py
#	roles/sys-stk-backend/tasks/_load_service.yml
#	roles/sys-stk-backend/vars/main.yml
#	roles/sys-svc-compose/templates/base.yml.j2
#	roles/sys-svc-mail/tasks/01_core.yml
#	roles/sys-utils-service-loader/tasks/load_frontend_service.yml
#	tests/unit/plugins/lookup/test_applications_current_play.py
#	tests/unit/plugins/lookup/test_service.py
#	tests/unit/roles/sys-stk-backend/lookup_plugins/test_service_should_load.py
2026-04-15 23:59:54 +02:00
kevinveenbirkenbachandClaude Opus 4.6 b70a783423 refactor(lookups): migrate to runtime applications/users lookups
Replaces inline `applications`/`users` merging with dedicated lookup
plugins and runtime hydration. Introduces `add_csp_hash` filter,
integrates sort into `find_dock_val_by_bkp_entr`, splits the Keycloak
one-shot realm import into `05a_realm_import_run.yml`, and fixes the
Mastodon administrator task YAML. Removes obsolete `csp_hashes` filter,
`sys-token-store` Jinja filter, and empty CLI setup modules.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 23:44:19 +02:00
Environment TestandClaude Opus 4.6 a07ef379ed chore(scripts): drop unused CA trust env pass-through from Playwright rerunner
The rendered .env already contains the deploy-time CA trust values and the
spec uses ignoreHTTPSErrors, so duplicating the Ansible task's -e wiring
never adds anything in the inner-loop case.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 20:31:03 +02:00
Environment TestandClaude Opus 4.6 53efeb7eb7 docs(agents): add Playwright Spec Loop with rerunner script
Adds the documented inner-loop workflow for iterating role-local
Playwright specs against a live stack without a full redeploy, plus
the helper script that reuses the existing staging dir, rendered .env,
and container image defaults so no new TEST_E2E_PLAYWRIGHT_* override
mechanism is introduced.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 20:22:26 +02:00
Environment TestandClaude Opus 4.6 a2275e6991 docs(make): pass variables after target to match Bash(make*) permission
Reorders all documented and scripted `make` invocations from the
`VAR=value make target` shell-env prefix form to the make-native
`make target VAR=value` form. GNU Make auto-exports both command-line
and inherited shell-env variables to recipe shells, so the change is
purely about command-line shape: only the make-suffix form starts with
`make` and is therefore matched by the `Bash(make*)` permission entry
in .claude/settings.json, avoiding unnecessary approval prompts for
agent runs.

Adds an explicit CLAUDE.md rule with ✅/❌ examples and the underlying
reason (permission prefix match, not Makefile semantics).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 12:28:44 +02:00
kevinveenbirkenbachandClaude Sonnet 4.6 3cfdc4bdf7 feat(services-disabler): propagate SERVICES_DISABLED through deploy stack and add conflict detection
Adds inventory consistency guard that fails fast when SERVICES_DISABLED
conflicts with an already-deployed inventory, and ensures the env var is
forwarded through the dedicated runner, development exec command, and
local test scripts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 19:36:16 +02:00
Environment Test f3d67ecb38 refactor(ci): extract app-discovery output logic into script
Inline shell duplicated across four deploy workflows. Single
source now in scripts/github/output_apps.sh.
2026-04-13 13:25:25 +02:00
Environment Test da155e48e8 refactor(ci): extract app-discovery output logic into script
Inline shell duplicated across four deploy workflows. Single
source now in scripts/github/output_apps.sh.
2026-04-13 13:22:20 +02:00
Environment Test ce000094b1 Merge branch 'main' into fix/free-disk-space/138
# Conflicts:
#	docs/contributing/artefact/git/branch.md
#	scripts/meta/resolve/pr/branch_prefix.sh
2026-04-11 14:33:11 +02:00
Environment Test 745ae310e2 fix(ci): allow update branch prefix 2026-04-11 14:29:32 +02:00
Environment TestandClaude Sonnet 4.6 afd332bb4e feat(ci): trigger orchestrator on alert-autofix-* branches
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 07:41:48 +02:00
Environment TestandClaude Sonnet 4.6 23d2e177f2 refactor(mirror): extract inline workflow scripts into standalone shell scripts
Move inline bash from images-mirror-all.yml and images-mirror-missing.yml
into dedicated scripts:
- scripts/meta/resolve/ghcr/namespace_and_repository.sh
- scripts/meta/mirror/sync_all.sh
- scripts/meta/mirror/sync_missing.sh

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 04:42:22 +02:00
Environment TestandClaude Sonnet 4.6 ac3b437733 fix(test): resolve self-exclusion bug in environment orchestrator
The self-exclusion check compared BASH_SOURCE[0] (relative path when
invoked as `bash ./scripts/…/00_orchestrator.sh`) against the glob-built
step paths (always absolute). The mismatch caused the orchestrator to
include itself in the loop, running a full inner pass of steps 01–10
before the outer loop repeated them — doubling the total runtime.

Fix: resolve SELF to an absolute path using SCRIPT_DIR so the comparison
is always path-equivalent regardless of invocation style.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 02:09:37 +02:00
Environment Test 212cc39052 test(external): split live registry checks
Keep live registry lookups out of the default make test flow.

Add a dedicated external suite, workflow, and docs so the check stays opt-in but still gates code CI when enabled.
2026-04-10 22:31:42 +02:00
Environment TestandClaude Sonnet 4.6 0b8e16a45d test(lint): add markdown link checker and fix all broken links
Add tests/lint/repository/test_markdown_links.py — a hard-fail lint
test that scans all git-tracked markdown files for broken relative and
repo-root-absolute links. Skips external URLs, anchor-only links, fenced
code blocks, and placeholder targets.

Apply documentation.md rules to all staged files: add emojis after
headlines in docs files, remove emojis from role README headings,
standardize Credits sections to the canonical format, remove empty
sections and orphaned sentences referring to missing documentation files,
fix raw URLs and incorrect link text across role READMEs and docs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 22:00:46 +02:00
Environment TestandClaude Sonnet 4.6 83262816a3 docs(contributing): apply documentation.md rules across all staged files
- Move emojis after headline text (CONTRIBUTING.md, actions/, design/, tools/, tests/)
- Replace em dashes with colons, semicolons, or complete sentences throughout
- Add missing emojis to all headlines in exceptions.md, principles.md, services.md, shell.md, setup.md, pull-request.md, commit.md, act.md, docker.md, pr/README.md
- Update H1 titles to reflect renamed directories (actions/, design/)
- Fix broken relative links in workflow.md after directory moves
- Fix full-path link texts in services.md (style.css.md, javascript.js.md)
- Fix broken principles.md link to lint.md after testing/ → actions/testing/ move

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 21:06:17 +02:00
Environment TestandClaude Sonnet 4.6 6835057707 fix(github): use owner:branch format for --head in gh pr create
When --repo is passed to gh, the --head argument must include the owner
in owner:branch format so GitHub can resolve the head SHA correctly.
Without it the GraphQL API returns 'Head sha can't be blank'.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 19:22:05 +02:00
Environment TestandClaude Sonnet 4.6 46f8f775c1 fix(github): use --force instead of --force-with-lease for update branch push
--force-with-lease requires a remote-tracking ref to exist locally. In a
fresh CI checkout the update branch has no tracking ref, so the push is
rejected as stale. The update branch is always owned by automation, so
--force is safe here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 19:20:22 +02:00