Skip to content

Releases: simonvanlierde/project-templates

v0.12.0

Choose a tag to compare

@github-actions github-actions released this 29 Oct 11:13
Immutable release. Only release title and notes can be modified.
v0.12.0
98e93f9

Upgrade steps:

  • Breaking: in a library, research or data-pipeline project, run just citation after the update and commit what it writes. Until you do, the new citation hook fails, in CI too. Add email: to the authors in CITATION.cff first, or codemeta.json loses the email it has.
  • With openssf_badge=silver: from this update on, sign off your own commits too (git commit -s, or git rebase --signoff origin/main for a branch you already have). Run prek install again so the new commit-msg hook is active.
  • If your README.md has the three-dot fair-software.eu badge and fair.yml scores under five of five, delete the badge line by hand. copier update never changes README.md.

Changed

  • New citable public projects no longer get a fair-software.eu badge at three of five dots. Add it once fair.yml scores five of five: set FAIR_MIN: 5 and paste the snippet howfairis prints in the job summary.
  • Breaking for openssf_badge=silver: the dco check runs on every pull request, the maintainers' branches included, as the silver badge's DCO criterion asks of every developer. A commit-msg hook refuses an unsigned commit before the push. Commits Dependabot or Renovate write in their own pull requests are exempt; a human commit on a bot's branch is still checked. The commit-msg hook accepts only a full Signed-off-by: Name <email> line, as the check does. just repo-settings also turns on GitHub's "require contributors to sign off on web-based commits", so a commit made in the web UI, such as "Commit suggestion", passes the check. Below silver, only pull requests from forks are checked, as before.
  • The copier-update workflow signs off its commit.
  • Pull requests restore the CI caches main saved and save none of their own, in every workflow that caches: uv, Rust, the pnpm store, Go, the git hook environments and trivy's database. GitHub lets only the pull request read a cache it saves, and a repo holds 10 GB of caches before it evicts the oldest, so those caches pushed out main's and new pull requests built cold. The pr title workflow, which runs on pull requests only, no longer caches uv.
  • codemeta.json declares CodeMeta 3.0 instead of 4.0, because Software Heritage's indexer reads only 2.0 and 3.0 and skipped the file. The fields are the same in both.
  • JSON files are checked by jsonvet 3.2.0, the new name of check-json5, in every project, not only TypeScript ones: .vscode/ and .github/rulesets/ JSON ship with every stack. It reads .json files as JSON5, so comments and trailing commas still pass, and fails on syntax errors and duplicate keys.

Fixed

  • The generated README had two blank lines before "Before the first release" (or before "License" in a project that publishes nothing), so the Markdown linter rewrote it on the first commit.
  • fair.yml called GitHub's API anonymously, so on a runner whose IP had used up its 60 requests an hour, howfairis scored checks as missing without an error. It now passes the job's token as APIKEY_GITHUB.
  • fair.yml scored the checklist as missing on every repo with an OpenSSF Best Practices badge, because the howfairis on PyPI (0.14.2) predates the www.bestpractices.dev badge URL. It now runs howfairis 0.15.0 from its GitHub tag, which reads that URL; PyPI has no 0.15.0 yet.
  • biome check failed on every new TypeScript project with biome 2.6, which formats Markdown and YAML too. biome.json now leaves those files to rumdl and yamlfmt.
  • just repo-settings in a public Renovate repo stopped with a bare "Validation Failed" when the Renovate app was not installed yet, because GitHub refuses an app it can't see as a bypass actor. It now shows GitHub's reason and says to install the app first.

Added

  • just citation writes .zenodo.json and codemeta.json from CITATION.cff, so you edit one file instead of three: title, description, authors with their ORCID iD, email and affiliation, licence and repository into both, and version, release date and DOI into codemeta.json only. Zenodo takes the version and date from the release, and would take a DOI for the release's own and mint none. Other top-level fields you add to the JSON files stay; the author lists are rewritten whole. A name particle such as van is kept in front of the family name. A git hook, which CI also runs, fails while the files disagree, and just citation --check runs the same check by hand.
  • docs/usage.md has a checklist for making a private repo public: a secret scan over the full history, the name on PyPI, crates.io and npm, a clean issue list and the README status sentence.
  • A Rust or Go binary and a Python data-pipeline get docs/accessibility.md: how the program prints (colour is never the only signal, NO_COLOR and --color never are honoured, plain output off a terminal, errors as file:line:col on standard error) and the author's email for problems. Check each claim holds for your program before you publish it. An existing project gets the file on copier update and keeps its own edits after that.
  • A public repo's CONTRIBUTING.md has a "Scope and response" section: one maintainer, a reply within about two weeks, an issue before a large pull request, and out-of-scope pull requests closed with a link to it.
  • A new status question (experimental, the default, stable, maintenance or archived, under customise) puts one status sentence under the README's badges. A public repo's README also says where questions and bugs go. An existing project's README is its own, so copier update adds neither: copy them from a fresh render.
  • A public repo gets issue forms in .github/ISSUE_TEMPLATE/: one for bugs and one for feature requests. Blank issues are turned off, and a link sends questions to CONTRIBUTING.md. Vulnerabilities go to private reporting, as before. A private repo gets none.
  • The template itself has a Zenodo DOI, 10.5281/zenodo.23701980, which always points to the newest release. CITATION.cff and the README carry it.

v0.11.0

Choose a tag to compare

@github-actions github-actions released this 27 Oct 19:52
Immutable release. Only release title and notes can be modified.
v0.11.0
75755da

Upgrade steps:

  • With publish_to_pypi: push the version tag and approve pypi; let python-release.yml
    create the GitHub release. It replaces release.yml and attaches the distributions
    and their provenance before publishing. Do not create the GitHub release by hand.
    If PyPI succeeds but the release job fails, delete any leftover draft and re-run
    only the release job (recovery steps).
  • Breaking: install Copier 9.19 or later (uv tool upgrade copier) before you run
    copier update. Renovate's copier manager installs the latest Copier.
  • Breaking: a web app made from an untagged main asks the new user_data question,
    which has no default, so copier update --defaults stops on it. Answer it, or pass it:
    copier update --data user_data=nothing (or browser, or accounts). Then add the
    footer and the page routing from a fresh render's src/App.tsx to yours, and
    /accessibility and /privacy (and /terms) to tests/e2e/routes.ts: an update
    leaves both files alone. Fill in the TODOs in docs/. An app on its own domain: pass
    --data site_url=https://<your domain>, or the pages name the pages.dev address.
    The weekly copier-update workflow fails until you have run this update by hand once.
  • Breaking: a private repo: pass --data public=false. The new public question
    is yes by default, so copier update --defaults, Renovate's update PR and the
    copier-update workflow add the public-repo files, including a scorecard.yml that
    fails in a private repo. With no, .github/SECURITY.md, CONTRIBUTING.md,
    CODE_OF_CONDUCT.md, pull_request_template.md, dco.yml and scorecard.yml go.
    Your license answer stays as it is.
  • A public repo: the update adds .github/CONTRIBUTING.md, CODE_OF_CONDUCT.md,
    pull_request_template.md and a dco check on pull requests from forks,
    and SECURITY.md gains a Scope section to fill in. GitHub shows .github/CONTRIBUTING.md
    before a root CONTRIBUTING.md, so if you have your own, keep one and delete the other.
  • With dependency_bot=dependabot: create a fine-grained token with read and write access
    to Contents, Pull requests and Workflows on the repo, and store it as the
    COPIER_UPDATE_TOKEN secret. Without it, the new weekly copier-update workflow opens
    an issue instead of a PR for an update that changes a workflow
    (Hearing about new releases).
  • README.md, CHANGELOG.md and the citation files (CITATION.cff, .zenodo.json,
    codemeta.json) are now your project's, and this update already leaves them alone. So
    this release's README changes don't arrive, such as the badges for the options you
    turned on and the Releasing section. Diff your README against a fresh render with your
    answers and copy the parts you want.
  • Breaking: if a ruleset or branch protection requires the lint, types, tests check
    (lint, types, pipeline, tests in a data-pipeline project), switch it to the new
    name: python: lint, types, tests (python: lint, types, pipeline, tests) or
    ts: lint, types, tests. A library runs one per Python version, named
    python: lint, types, tests (3.12) and so on. Until then, pull requests wait on a
    check that never reports.
  • Run just repo-settings once after the update, and in a new project after the first
    push. It protects main and the v* tags and, in a public repo, turns on private
    vulnerability reporting, which SECURITY.md points to. main then requires the git hooks,
    pull request title, dependency review and, in a public repo, DCO sign-off checks: if
    you renamed any of those jobs, edit .github/rulesets/main.json first (in a public repo,
    main-checks.json), or pull requests wait on a check that never reports. In a public
    repo, main also requires an approval from now on; as the repo admin you can merge your
    own pull requests by ticking the bypass box in the merge box.
  • Run prek install again in each clone, so the new commit-msg hook is installed.
  • The new typos and lychee hooks run on every file in CI's git hooks job. After the
    update, run prek run --all-files typos lychee, review what typos fixed, and fix the
    dead links lychee lists, or that job fails.
  • After the update, refresh the lockfiles for your stacks and commit them: uv lock,
    pnpm install, just go-sync. This release bumps dev tools in every stack, and CI
    installs with --locked and --frozen-lockfile.
  • A TypeScript library with publish_to_npm: after the update, run just ts-api and
    commit <package>.api.md. The template's copy describes the sample add function, not
    your exports, so CI fails until you do.
  • With dependency_bot=renovate: turn Dependabot security updates off
    (gh api -X DELETE repos/OWNER/REPO/automated-security-fixes), or each security fix
    arrives as two PRs. Keep Dependabot alerts on: Renovate's security PRs need them.
  • Breaking: in a Go library made with v0.10.0 or earlier, copier update deletes
    <package>_test.go without asking, your changes to it included, and adds
    add_test.go. Before you commit the update, run git checkout HEAD -- <package>_test.go
    (after committing it, git checkout HEAD~1 -- <package>_test.go). Then delete
    add_test.go, or the two TestAdd functions stop the tests compiling. With
    test_extras=[property], first copy FuzzAdd from add_test.go into your test file.
  • In a Python or TypeScript library, the new sample add function arrives as a conflict
    in src/<module>/__init__.py or src/index.ts: keep your own side. Then delete
    tests/test_add.py, and the add import and test the update merged into
    src/index.test.ts, or those tests fail.
  • In a data-pipeline project (see the two Breaking changes below):
    • src/<module>/pipeline.py becomes a short file that imports sourceledger. If you
      added readers to parse, keep only your own branches, end it with
      return sourceledger.parse_source(source, payload), and keep the imports your
      branches need: the new file no longer imports csv or io.
    • Take the new tests/test_pipeline.py, and keep any tests of your own readers.
    • pyproject.toml gains the sourceledger dependency. Keep any dependencies of your
      own next to it, where copier update can't merge the two lists.
    • In sources.toml, rename release to vintage (the old key still works, with a
      warning). Give each implemented source a license (an SPDX id, or
      LicenseRef-<name>) and redistribute = true or false. Rename any source id with
      a non-ASCII letter: only ASCII letters, digits, _ and - are accepted.
    • Run just pipeline. just validate reports a missing datapackage.json until
      just build has written one.
  • Breaking: python-release.yml and ts-release.yml now run when a vX.Y.Z tag is
    pushed, not when a GitHub release is published. Add the ## [X.Y.Z] section to
    CHANGELOG.md before you tag. The release workflow reads that section and fails
    when it is missing. Releases created by GITHUB_TOKEN don't start other
    workflows, so the publish workflows could not follow the release.

Added

  • Weekly Go property runs cache generated fuzz inputs so each run resumes the
    coverage the previous runs found.
  • Copier and howfairis workflow pins follow template updates. Renovate tracks their
    versions in the template, so they no longer need separate manual bumps.
  • The code of conduct tells readers that a report about the maintainer can go to GitHub
    instead, through Report abuse.
  • An openssf_badge question, asked in a public repo with a license, for the
    OpenSSF Best Practices badge. passing adds a test
    policy and each stack's coding standards to .github/CONTRIBUTING.md. silver also
    adds GOVERNANCE.md, docs/roadmap.md and docs/assurance-case.md, short skeletons
    you fill in and then own. It defaults to none, so an update changes nothing unless
    you pass --data openssf_badge=passing (or silver).
  • A cold-install.yml workflow runs the shell blocks under the README's ## Development
    heading as written, in a Debian container with only the tools the README says you
    need, so a setup step the README leaves out fails in CI. It runs weekly and on pull
    requests that change README.md. It skips just up, just pipeline, just ts-e2e
    and the mutation and property recipes, which need Docker, a browser, live sources or hours.
    Your README stays yours on copier update, so the job runs whatever it says now.
  • Spelling and link checks. A typos git hook finds misspelt words and a lychee hook
    finds relative links to missing files in Markdown and HTML. The lychee hook runs
    offline, so a new weekly links.yml workflow checks the web links too. List a word
    typos must leave alone in _typos.toml (Spelling and link checks).
  • A short AGENTS.md in every project, for coding agents: the just check command, each
    stack's test recipe and where the docs are. It names only recipes the project's
    justfile has.
  • Commit message rules in committed.toml: Conventional Commits, an imperative summary,
    no period. A committed commit-msg hook checks each commit, skipping merge
    commits, and a new pr-title.yml workflow checks the pull request title, which a squash
    merge turns into the commit subject. Dependabot and Renovate now write PR titles in the
    same form, chore(deps): ....
  • GPL-3.0-or-later and AGPL-3.0-or-later as license answers, with
    the GNU texts in LICENSE. These texts have no copyright line, so they don't ask
    copyright_year.
  • A python_layout question under customise, src by default. flat is for adopting
    the template in a repo whose package already sits at the root: it renders no
    src/<module> stub or tests/test_add.py, and sets `mod...
Read more

v0.10.0

Choose a tag to compare

@simonvanlierde simonvanlierde released this 17 Oct 16:19
Immutable release. Only release title and notes can be modified.
7119fc2

What's Changed

  • fix(codecov): carry each stack's coverage forward until its report arrives by @simonvanlierde in #54
  • feat: ask which dependency bot a project uses, dependabot by default by @simonvanlierde in #55
  • fix(codecov): comment only on untested new lines by @simonvanlierde in #56
  • fix(data-pipeline): per-source download cap and a pipeline-specific pyproject comment by @simonvanlierde in #57
  • feat(data-pipeline): retry a failed fetch and record Last-Modified and ETag by @simonvanlierde in #58

Full Changelog: v0.9.1...v0.10.0

v0.9.0

Choose a tag to compare

@simonvanlierde simonvanlierde released this 13 Oct 02:00
Immutable release. Only release title and notes can be modified.
ed9a609

Added

  • A codecov option for the Python and TS stacks: CI uploads test coverage to Codecov, and a codecov.yml fails a pull request only when total coverage drops by more than 2 points. Codecov comments only then. It needs a CODECOV_TOKEN repository secret (see the README).

v0.8.1

Choose a tag to compare

@simonvanlierde simonvanlierde released this 13 Oct 00:54
Immutable release. Only release title and notes can be modified.

A fix for private repositories. Nothing breaks.

What changes in your project

  • Dependency review skips private repositories. GitHub runs it there only with Advanced Security, so the job failed every pull request. The stack workflows' dependency audits still run.

Upgrading from v0.8.0

Run copier update.

v0.8.0

Choose a tag to compare

@simonvanlierde simonvanlierde released this 13 Oct 00:37

No more personal defaults, citation files for libraries, and libraries tested on every supported Python. Two changes are breaking.

What changes in your project

  • No personal defaults. The GitHub user, author name, email and ORCID iD no longer default to the template author's. Copier asks for them, or reads them from the defaults: in your Copier settings file (see the README).
  • Citation files. library, research and data-pipeline projects get CITATION.cff, .zenodo.json for Zenodo, and a CodeMeta 4.0 codemeta.json.
  • Libraries are tested on every supported Python. A new python_min answer, two minors below python_version by default (after SPEC 0), sets requires-python. CI tests every version from there up.
  • Breaking: data-pipeline drops the vintage_basis column and the per-source encoding key. A source can pin a sha256, and fetch refuses a download that doesn't match it.
  • Security: the Python workflow checks every package against OSV's malware advisories before it runs. The generated README installs golangci-lint with go install, checked against the Go checksum database. Release workflows lose workflow_dispatch.
  • The web service's API docs are off unless API_DOCS is set, CI skips draft pull requests, and VS Code formats TOML with Tombi.

Upgrading from v0.7.1

  1. Run copier update. Your saved answers carry over. A library is asked for python_min.
  2. In a library that added a dependency, pyproject.toml conflicts once at requires-python: take the new floor and keep your dependencies.
  3. In a data-pipeline project, re-run just pipeline.
  4. Scripts that run copier copy --defaults must now pass --data github_user=… --data author_name=… --data author_email=…, or set them in Copier's settings file.

The full list is in CHANGELOG.md.

v0.7.1

Choose a tag to compare

@simonvanlierde simonvanlierde released this 30 Sep 18:00
6d0c10f

A small release: a Rust sync recipe, YAML formatting, and clearer docs. Nothing breaks.

What changes in your project

  • just rs-sync downloads Rust dependencies and writes Cargo.lock, like
    just py-sync, just ts-sync and just go-sync do for their stacks.
  • A yamlfmt hook formats YAML files. yamllint now checks yamlfmt's output, and
    flow mappings are written {key: value}.
  • Hook revs are commit SHAs, with a # frozen: comment naming the tag, because
    tags can move. Dependabot updates both together.
  • Comments and docstrings in generated files are shorter and plainer.

Upgrading from v0.7.0

  1. Run copier update.
  2. Run prek run -a once, so yamlfmt formats your existing YAML files.

The full list is in
CHANGELOG.md.

v0.7.0

Choose a tag to compare

@simonvanlierde simonvanlierde released this 30 Sep 17:33
419a61a

A cleanup release: less duplication, less dead config, and nothing that breaks.

What changes in your project

  • hygiene.yml is now checks.yml. Job names are unchanged, so required status
    checks still match.
  • .tombi.toml replaces .taplo.toml, because tombi replaced taplo as the TOML
    formatter.
  • Coverage recipes print a summary only. just py-cov and just ts-cov no longer
    write coverage.xml or coverage/lcov.info.
  • Removed: the pull request template, and the unused knip script
    (pnpm run check still runs knip).

Upgrading from v0.6.0

  1. Run copier update.
  2. If something uploads coverage reports, add the reporter flag back to just py-cov
    or just ts-cov.

The full list is in
CHANGELOG.md.

v0.6.0

Choose a tag to compare

@simonvanlierde simonvanlierde released this 30 Sep 16:37
231b0f6

Two new stacks, two new Python project kinds, and a lot of hardening.

Highlights

  • Rust and Go stacks. Each comes as a library or a binary, with strict linting, tests, CI and
    Dependabot.
  • Python web-service: a FastAPI app in a container, with /health and opt-in OpenTelemetry.
  • Python data-pipeline: downloads third-party data, records a checksum for each file and
    rebuilds a dataset from it.
  • Dependency audits in just check and CI for Python, TypeScript, Rust and Go. New releases
    wait a week before uv or pnpm install them.
  • Safer answers. Copier rejects answers that used to produce a broken project, such as a name
    that starts with a digit.
  • A CHANGELOG.md in every new project.

Breaking changes

  • Secret scanning uses Betterleaks instead of gitleaks.
  • Vale is gone. rumdl still lints Markdown.
  • The web service's config.py and telemetry.py are gone. OpenTelemetry turns on only when
    OTEL_EXPORTER_OTLP_ENDPOINT is set.

Upgrading from v0.5.0

  1. Run copier update. If you added dependencies, you get one conflict in pyproject.toml. Keep
    your dependencies and take the new comment below them.
  2. Run uv lock and pnpm install, then commit the lockfiles.
  3. If a SKIP list names gitleaks, change it to betterleaks.
  4. Delete the .vale/ folder.

The full list is in
CHANGELOG.md.

v0.5.0

Choose a tag to compare

@simonvanlierde simonvanlierde released this 30 Jul 16:03
1e701ab

Full Changelog: v0.4.0...v0.5.0