Skip to content

Fix generated-project CI, gate releases on CI, and tighten init/install rules - #6

Merged
catyugu merged 4 commits into
mainfrom
agent/dev
Oct 23, 2026
Merged

catyugu merged 4 commits into
mainfrom
agent/dev

Conversation

@catyugu

@catyugu catyugu commented Oct 23, 2026

Copy link
Copy Markdown
Owner

Reliability pass over the template: fix the generated-project CI, gate releases on the tagged commit's CI, harden the initializer, and tighten the packaging rules.

1. Generated projects no longer run the template's initializer test

est_template.py used to initialize a copy and assert the fixed names FreshProject/reshproject. Any project initialized to another name kept that script, and its own CI then re-ran an initialization whose placeholders were already gone.
  • The template check now initializes a non-default project (AwesomeApp/�wesome), asserts the result (directories renamed, README regenerated, template-only files removed, no placeholders left), checks that invalid names are rejected before the tree is touched, and then runs that project's own format and package checks.
  • The template job moved to its own emplate.yml; the initializer removes it, est_template.py and itself from the generated project. ci.yml in a generated project is the generic 7-job pipeline.
  • Regression coverage is a non-default name end to end: python .github/scripts/test_template.py.

2. Releases wait for the tagged commit's CI

elease.yml published after one Ubuntu template check, so v1.0.0 could publish 26 s before the main CI finished.

wait_for_ci.py now waits for every push-triggered workflow of the tagged commit (discovered from the commit's own runs, so a generated project is gated by its ci.yml alone), ignores the release run started by the tag push itself, follows rerun attempts, retries through transient API errors, and fails on a failed/cancelled run or timeout. The script has an offline --self-test that emplate.yml runs on every PR.

3. Initializer hardening

  • Project name and namespace must be identifiers (letters, digits, underscore; namespace lowercase), validated before any file is touched; the template placeholders themselves are rejected.
  • Non-interactive --project-name / --namespace arguments.
  • Build directories follow .gitignore (�uild-* was rewritten before); only UTF-8 text files are rewritten, and a rename/write failure now exits non-zero instead of printing "Skipping" and reporting success.
  • The generated project gets its own README.md, and the template-only files are removed.

4. Build and install rules

  • .cxx/.c++ sources are compiled; .hxx/.inl/.ipp/.tpp are listed for IDEs.
  • include/ is installed wholesale instead of a .h/.hpp whitelist, and check_build.py compares the source tree with the installed tree so a future whitelist cannot silently drop files.

5. Eigen is a build-only dependency

$<BUILD_LOCAL_INTERFACE:...> keeps Eigen out of the installed static target; mt stays a real exported link dependency. The consumer test asserts Eigen is not exported and configures with the Eigen lookup disabled.

Verification

Locally (clang 23 / Ninja, Windows): --scope package for both linkagings, --scope embedded, the .cxx/.inl probe, and the full est_template.py (init → generated project's format + static/shared package + embedded). CI runs the same on Linux, macOS and Windows.

test_template.py used to re-initialize a copy of the tree and assert the
fixed names FreshProject/freshproject. A project initialized to any other
name kept that script, and its CI then failed because the placeholders it
re-initialized were already gone.

Now the template test initializes a non-default project (AwesomeApp/awesome),
checks the result (renamed directories, regenerated README, template-only
files removed, no placeholders left), rejects invalid names before touching
the tree, and finally runs that project's own format and package checks.
The initializer removes the template test, its workflow and itself from the
generated project, so a downstream repository never re-runs an
initialization that cannot succeed.

init_project.py also validates both names as identifiers, follows .gitignore
for build directories (build-*/ was rewritten before), rewrites only UTF-8
text files and fails instead of skipping when a file cannot be written.
- Build .cxx/.c++ sources that the glob used to miss, and list .hxx/.inl/
  .ipp/.tpp in the header globs so they show up for IDEs.
- Install the whole include/ tree instead of a .h/.hpp whitelist: a public
  header that includes a .inl/.ipp/.tpp companion must not be installed
  half-complete. check_build.py now compares the source tree with the
  installed one, so a future whitelist cannot silently drop files.
- Make Eigen a build-only dependency with \$<BUILD_LOCAL_INTERFACE:...>: it is
  header-only and absent from the public headers, so the installed static
  target no longer asks consumers for Eigen. fmt stays a real exported link
  dependency. The consumer test asserts that Eigen is not exported and
  configures with the Eigen lookup disabled to prove it is not required.
The release ran its own Ubuntu template check and then published, so it
could finish before the Windows or macOS jobs of the same commit. It now
waits for every push-triggered workflow of the tagged commit (ci.yml and
template.yml here, ci.yml alone in a generated project) and fails if any of
them failed, was cancelled or did not complete within the timeout.

wait_for_ci.py discovers the required set from the commit's own runs
instead of hardcoding workflow names, ignores the release run that the tag
push itself started, follows rerun attempts, and keeps polling through
transient API errors. Its selection logic has an offline self-test that the
template job runs on every pull request.
@catyugu
catyugu merged commit 5f0bd35 into main Oct 23, 2026
8 checks passed
@catyugu
catyugu deleted the agent/dev branch October 23, 2026 18:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant