From a758d446e86b9748b3f0d9b00c269e8fe61c3099 Mon Sep 17 00:00:00 2001 From: martonvago Date: Tue, 5 Aug 2025 10:28:00 +0100 Subject: [PATCH 01/30] feat: :sparkles: add files with copier variables to template folder --- .gitignore | 1 + copier.yaml | 125 ++++++++++++++++ justfile | 134 ++++++++++-------- template/.github/CODEOWNERS.jinja | 13 ++ template/.github/dependabot.yml.jinja | 14 ++ .../workflows/add-to-project.yml.jinja | 27 ++++ template/CITATION.cff.jinja | 24 ++++ template/LICENSE.md.jinja | 21 +++ template/README.md.jinja | 3 + template/_quarto.yml.jinja | 73 ++++++++++ ...oject %}site-counter.html{% endif %}.jinja | 3 + template/index.qmd.jinja | 5 + template/pyproject.toml.jinja | 38 +++++ .../{{package_name_snake_case}}/__init__.py | 1 + .../src/{{package_name_snake_case}}/py.typed | 0 template/{{_copier_conf.answers_file}}.jinja | 2 + 16 files changed, 421 insertions(+), 63 deletions(-) create mode 100644 copier.yaml create mode 100644 template/.github/CODEOWNERS.jinja create mode 100644 template/.github/dependabot.yml.jinja create mode 100644 template/.github/workflows/add-to-project.yml.jinja create mode 100644 template/CITATION.cff.jinja create mode 100644 template/LICENSE.md.jinja create mode 100644 template/README.md.jinja create mode 100644 template/_quarto.yml.jinja create mode 100644 template/docs/{% if seedcase_project %}site-counter.html{% endif %}.jinja create mode 100644 template/index.qmd.jinja create mode 100644 template/pyproject.toml.jinja create mode 100644 template/src/{{package_name_snake_case}}/__init__.py rename src/PACKAGE-NAME/__init__.py => template/src/{{package_name_snake_case}}/py.typed (100%) create mode 100644 template/{{_copier_conf.answers_file}}.jinja diff --git a/.gitignore b/.gitignore index 6346a65..21ac9de 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ _ignore bin/ dev/ +_temp/ # Temporary files *.tmp diff --git a/copier.yaml b/copier.yaml new file mode 100644 index 0000000..38e0de0 --- /dev/null +++ b/copier.yaml @@ -0,0 +1,125 @@ +_subdirectory: template + +# Post-copy commands: +_tasks: + # Add dev dependencies + - command: "git init -b main && uv add --dev pre-commit ruff typos pytest bandit commitizen genbadge jupyter pytest-cov quartodoc types-tabulate mypy vulture" + when: "{{ _copier_operation == 'copy' }}" + # If Seedcase project, add seedcase-theme extension + - command: "uv run quarto add --no-prompt seedcase-project/seedcase-theme" + when: "{{ _copier_operation == 'copy' and is_seedcase_project }}" + # If Seedcase project, use seedcase-theme as project type + - command: >- + uv run python -c "from pathlib import Path; file = Path('_quarto.yml'); file.write_text(file.read_text().replace('type: website', 'type: seedcase-theme', 1))" + when: "{{ _copier_operation == 'copy' and is_seedcase_project }}" + + +# Message to show after generating or regenerating the project successfully +_message_after_copy: | + + Your project "{{ package_name }}" has been created successfully! + + Next steps: + + 1. Change directory to the project root: + + $ cd {{ _copier_conf.dst_path }} + + 2. Install the pre-commit hooks: + + $ just install-precommit + + 3. Install [`spaid`](https://github.com/seedcase-project/spaid) and run these commands to upload and configure your project on GitHub: + + $ spaid_gh_create_repo_from_local -h + $ spaid_gh_set_repo_settings -h + $ spaid_gh_ruleset_basic_protect_main -h + + 4. Configure GitHub following this + [guide](https://guidebook.seedcase-project.org/operations/security#using-github-apps-to-generate-tokens): + + - Install the [auto-release-token](https://github.com/apps/auto-release-token) GitHub App + - Create these secrets: UPDATE_VERSION_TOKEN, ADD_TO_BOARD, NETLIFY_AUTH_TOKEN + - Create these variables: UPDATE_VERSION_APP_ID, ADD_TO_BOARD_APP_ID + + 5. List and complete all TODO items in the repository: + + $ just list-todos + +# Questions: +github_user: + type: str + help: "What is the GitHub username of the person or organisation who owns the package?" + validator: | + {% if github_user and not (github_user | regex_search('^[\w.-]+$')) %} + Must contain only alphanumeric characters and `_`, `-`, or `.`. + {% endif %} + +package_name: + type: str + help: "What is the name of the package?" + default: "{{ _copier_conf.dst_path | basename }}" + validator: | + {% if package_name and not (package_name | regex_search('^[\w.-]+$')) %} + Must contain only alphanumeric characters and `_`, `-`, or `.`. + {% endif %} + +package_name_snake_case: + type: str + default: "{{package_name | replace('-', '_') | replace('.', '_')}}" + when: false + +package_github_repo: + type: str + default: "{{ github_user ~ '/' ~ package_name }}" + when: false + +is_seedcase_project: + type: bool + help: "Is this package part of the Seedcase Project?" + default: "{{ github_user == 'seedcase-project' }}" + +seedcase_short_name: + type: str + help: "What is the short name of the package?" + default: "{{ package_name[9:] if ('seedcase-' in package_name) else '' }}" + when: "{{ is_seedcase_project }}" + +homepage: + type: str + help: "What is the homepage of your project?" + default: "{{ 'https://%s.seedcase-project.org' % seedcase_short_name if is_seedcase_project else '' }}" + +author_given_name: + type: str + help: "What is your first/given name?" + +author_family_name: + type: str + help: "What is your last/family name?" + +author_email: + type: str + help: "What is your email address?" + +review_team: + type: str + help: What GitHub team is responsible for reviewing pull requests? + default: "{{ '@%s/developers' % github_user if github_user else '' }}" + +github_board_number: + type: str + help: "What is the number of the GitHub project board to add issues and PRs to?" + validator: | + {% if github_board_number and not github_board_number.isdigit() %} + The board number must be an integer. + {% endif %} + +copyright_year: + type: str + default: "{{ copyright_year | default('%Y' | strftime) }}" + when: false + +dependabot_pr_assignee: + type: str + help: "What is the GitHub username of the person to assign to PRs opened by dependabot?" diff --git a/justfile b/justfile index b009dfd..f26f5ba 100644 --- a/justfile +++ b/justfile @@ -2,7 +2,7 @@ just --list --unsorted # Run all build-related recipes in the justfile -run-all: install-deps format-python check-python check-unused test-python check-security check-spelling check-commits build-website +run-all: check-spelling check-commits test build-website # Install the pre-commit hooks install-precommit: @@ -13,78 +13,86 @@ install-precommit: # Update versions of pre-commit hooks uvx pre-commit autoupdate -# Install Python package dependencies -install-deps: - uv sync --all-extras --dev - -# Run the Python tests -test-python: - uv run pytest - # Make the badge from the coverage report - uv run genbadge coverage \ - -i coverage.xml \ - -o htmlcov/coverage.svg - -# Check Python code for any errors that need manual attention -check-python: - # Check formatting - uv run ruff check . - # Check types - uv run mypy . - -# Reformat Python code to match coding style and general structure -format-python: - uv run ruff check --fix . - uv run ruff format . - -# Build the documentation website using Quarto -build-website: - # To let Quarto know where python is. - export QUARTO_PYTHON=.venv/bin/python3 - # Delete any previously built files from quartodoc. - # -f is to not give an error if the files don't exist yet. - rm -f docs/reference/*.qmd - uv run quartodoc build - uv run quarto render --execute - -# Run checks on commits with non-main branches +# Check the commit messages on the current branch that are not on the main branch check-commits: #!/bin/zsh branch_name=$(git rev-parse --abbrev-ref HEAD) number_of_commits=$(git rev-list --count HEAD ^main) if [[ ${branch_name} != "main" && ${number_of_commits} -gt 0 ]] then - uv run cz check --rev-range main..HEAD + uvx --from commitizen cz check --rev-range main..HEAD else - echo "Can't either be on ${branch_name} or have more than ${number_of_commits}." + echo "On `main` or current branch doesn't have any commits." fi -# Run basic security checks on the package -check-security: - uv run bandit -r src/ - # Check for spelling errors in files check-spelling: - uv run typos + uvx typos -# Build the documentation as PDF using Quarto -build-pdf: - # To let Quarto know where python is. - export QUARTO_PYTHON=.venv/bin/python3 - uv run quarto install tinytex - # For generating images from Mermaid diagrams - uv run quarto install chromium - uv run quarto render --profile pdf --to pdf - find docs -name "mermaid-figure-*.png" -delete +# Test and check that a Python package can be created from the template +test: + #!/bin/zsh + test_name="test-python-package" + test_dir="$(pwd)/_temp/$test_name" + template_dir="$(pwd)" + commit=$(git rev-parse HEAD) + rm -rf $test_dir + # vcs-ref means the current commit/head, not a tag. + uvx copier copy $template_dir $test_dir \ + --vcs-ref=$commit \ + --defaults \ + --trust \ + --data github_user="first-last" \ + --data package_name=$test_name \ + --data is_seedcase_project=true \ + --data author_given_name="First" \ + --data author_family_name="Last" \ + --data author_email="first.last@example.com" \ + --data review_team="@first-last/developers" \ + --data github_board_number=22 \ + --data dependabot_pr_assignee="mango90" + # Run checks in the generated test Python package + cd $test_dir + git add . + git commit -m "test: initial copy" + just check-python check-spelling + # TODO: Find some way to test the `update` command + # Check that recopy works + echo "Testing recopy command -----------" + rm .cz.toml + git add . + git commit -m "test: preparing to recopy from the template" + uvx copier recopy \ + --vcs-ref=$commit \ + --defaults \ + --overwrite \ + --trust + # Check that copying onto an existing Python package works + echo "Using the template in an existing package command -----------" + rm .cz.toml .copier-answers.yml LICENSE.md + git add . + git commit -m "test: preparing to copy onto an existing package" + uvx copier copy \ + $template_dir $test_dir \ + --vcs-ref=$commit \ + --defaults \ + --trust \ + --overwrite \ + --data github_user="first-last" \ + --data package_name=$test_name \ + --data is_seedcase_project=true \ + --data author_given_name="First" \ + --data author_family_name="Last" \ + --data author_email="first.last@example.com" \ + --data review_team="@first-last/developers" \ + --data github_board_number=22 \ + --data dependabot_pr_assignee="mango90" -# Check for unused code in the package and its tests -check-unused: - # exit code=0: No unused code was found - # exit code=3: Unused code was found - # Three confidence values: - # - 100 %: function/method/class argument, unreachable code - # - 90 %: import - # - 60 %: attribute, class, function, method, property, variable - # There are some things should be ignored though, with the allowlist. - # Create an allowlist with `vulture --make-allowlist` - uv run vulture src/ tests/ **/vulture-allowlist.py +# Clean up any leftover and temporary build files +cleanup: + #!/bin/zsh + rm -rf _temp + +# Build the website using Quarto +build-website: + uvx --from quarto quarto render diff --git a/template/.github/CODEOWNERS.jinja b/template/.github/CODEOWNERS.jinja new file mode 100644 index 0000000..172a7e0 --- /dev/null +++ b/template/.github/CODEOWNERS.jinja @@ -0,0 +1,13 @@ +# All members on Developers team get added to review PRs +* {{ review_team }} + +# Ignore these so we don't get added to sync PRs +/.github/ +/.vscode/ +/.devcontainer/ +justfile +.editorconfig +.gitignore +ruff.toml +pyproject.toml +uv.lock diff --git a/template/.github/dependabot.yml.jinja b/template/.github/dependabot.yml.jinja new file mode 100644 index 0000000..76c25b2 --- /dev/null +++ b/template/.github/dependabot.yml.jinja @@ -0,0 +1,14 @@ +version: 2 +updates: + - package-ecosystem: pip + directory: / + schedule: + interval: monthly + versioning-strategy: increase-if-necessary + commit-message: + prefix: build + include: scope +{%- if dependabot_pr_assignee %} + assignees: + - "{{ dependabot_pr_assignee }}" +{% endif %} diff --git a/template/.github/workflows/add-to-project.yml.jinja b/template/.github/workflows/add-to-project.yml.jinja new file mode 100644 index 0000000..955b8d5 --- /dev/null +++ b/template/.github/workflows/add-to-project.yml.jinja @@ -0,0 +1,27 @@ +name: Add to project board + +on: + issues: + types: + - opened + - reopened + - transferred + pull_request: + types: + - reopened + - opened + +# Limit token permissions for security +permissions: read-all + +jobs: + add-to-project: + uses: seedcase-project/.github/.github/workflows/reusable-add-to-project.yml@main + permissions: + pull-requests: write + with: + board-number: {{ github_board_number }} + app-id: {{ '${{ vars.ADD_TO_BOARD_APP_ID }}' }} + secrets: + add-to-board-token: {{ '${{ secrets.ADD_TO_BOARD }}' }} + gh-token: {{ '${{ secrets.GITHUB_TOKEN }}' }} diff --git a/template/CITATION.cff.jinja b/template/CITATION.cff.jinja new file mode 100644 index 0000000..c03cb5b --- /dev/null +++ b/template/CITATION.cff.jinja @@ -0,0 +1,24 @@ +# TODO: Add title of Python package. +title: "" +# TODO: Add abstract of Python package. +abstract: "" +authors: + - family-names: {{ author_family_name }} + given-names: {{ author_given_name }} + # TODO: Add ORCID and affiliation for the author. + orcid: "" + affiliation: "" + # TODO: Add more authors as needed. + # - family-names: "" + # given-names: "" + # orcid: "" + # affiliation: "" +cff-version: 1.2.0 +# doi: +keywords: + # TODO: Add keywords relevant to the project. + - "" +license: MIT +message: "If you use this Python package, please cite it using these metadata." +repository-code: "https://github.com/{{ package_github_repo }}" +url: "{{ homepage }}" diff --git a/template/LICENSE.md.jinja b/template/LICENSE.md.jinja new file mode 100644 index 0000000..8b1ba0a --- /dev/null +++ b/template/LICENSE.md.jinja @@ -0,0 +1,21 @@ +# MIT License + +Copyright (c) {{ copyright_year }} {{ package_name }} authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/template/README.md.jinja b/template/README.md.jinja new file mode 100644 index 0000000..117f38b --- /dev/null +++ b/template/README.md.jinja @@ -0,0 +1,3 @@ +# {{ package_name }} + + diff --git a/template/_quarto.yml.jinja b/template/_quarto.yml.jinja new file mode 100644 index 0000000..ce79abd --- /dev/null +++ b/template/_quarto.yml.jinja @@ -0,0 +1,73 @@ +project: + type: website + # Delete auto-generated files from `quartodoc` + post-render: rm -f docs/reference/*.qmd + render: + - "docs/*" + - "index.qmd" + +website: + title: "{{ 'Seedcase ' ~ (seedcase_short_name | title) if is_seedcase_project else package_name }}" + site-url: "{{ homepage }}" + repo-url: "https://github.com/{{ package_github_repo }}" + page-navigation: true + navbar: + pinned: true + title: false + {%- if is_seedcase_project %} + logo: "_extensions/seedcase-project/seedcase-theme/logos/navbar-logo-seedcase-{{ seedcase_short_name }}.svg" + logo-alt: "Seedcase {{ seedcase_short_name | title }} logo: Main page" + {%- else %} + # TODO: add logo + logo: "" + logo-alt: "{{ package_name }} logo: Main page" + {%- endif %} + left: + - text: "Guide" + href: docs/guide/index.qmd + - text: "Design" + href: docs/design/index.qmd + tools: + - icon: github + href: "https://github.com/{{ package_github_repo }}" + aria-label: "GitHub icon: Source code" + - icon: house + href: "{{ 'https://seedcase-project.org' if is_seedcase_project else homepage }}" + aria-label: "House icon: {{ 'Seedcase Project' if is_seedcase_project else package_name }} home page" + sidebar: + - id: design + pinned: true + style: "floating" + contents: + - text: "Design" + href: docs/design/index.qmd + - id: guide + contents: + - section: "Guide" + href: docs/guide/index.qmd + +quartodoc: + sidebar: "docs/reference/_sidebar.yml" + style: "pkgdown" + dir: "docs/reference" + package: "{{ package_name_snake_case }}" + parser: google + dynamic: true + renderer: + style: _renderer.py + table_style: description-list + show_signature_annotations: true + +metadata-files: + - docs/reference/_sidebar.yml +{% if is_seedcase_project %} +format: + seedcase-theme-html: + include-before-body: + - "docs/site-counter.html" +{%- endif %} + +editor: + markdown: + wrap: 72 + canonical: true diff --git a/template/docs/{% if seedcase_project %}site-counter.html{% endif %}.jinja b/template/docs/{% if seedcase_project %}site-counter.html{% endif %}.jinja new file mode 100644 index 0000000..5156b87 --- /dev/null +++ b/template/docs/{% if seedcase_project %}site-counter.html{% endif %}.jinja @@ -0,0 +1,3 @@ + + diff --git a/template/index.qmd.jinja b/template/index.qmd.jinja new file mode 100644 index 0000000..d567c08 --- /dev/null +++ b/template/index.qmd.jinja @@ -0,0 +1,5 @@ +--- +title: "Welcome to {{ 'Seedcase ' ~ (seedcase_short_name | title) if is_seedcase_project else package_name }}!" +--- + +{{ "{{< include /docs/includes/_wip.qmd >}}" }} diff --git a/template/pyproject.toml.jinja b/template/pyproject.toml.jinja new file mode 100644 index 0000000..7ae59ce --- /dev/null +++ b/template/pyproject.toml.jinja @@ -0,0 +1,38 @@ +[project] +name = "{{ package_name }}" +version = "0.1.0" +# TODO: Add a description of the package. +description = "" +authors = [ + {name = "{{ author_given_name }} {{ author_family_name }}", email = "{{ author_email }}" }, + # TODO: Add more authors as needed. +] +maintainers = [ + {name = "{{ author_given_name }} {{ author_family_name }}", email = "{{ author_email }}" }, + # TODO: Add more maintainers as needed. +] +readme = "README.md" +license = "MIT" +license-files = ["LICENSE.md"] +requires-python = ">=3.12" +dependencies = [] + +[project.urls] +homepage = "{{ homepage }}" +{%- if package_github_repo %} +repository = "https://github.com/{{ package_github_repo }}" +changelog = "https://github.com/{{ package_github_repo }}/blob/main/CHANGELOG.md" +issues = "https://github.com/{{ package_github_repo }}/issues" +{% endif %} + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.pytest.ini_options] +addopts = [ + # A short traceback mode to make it easier to view + "--tb=short", + # Use the `src/` package + "--import-mode=importlib", +] diff --git a/template/src/{{package_name_snake_case}}/__init__.py b/template/src/{{package_name_snake_case}}/__init__.py new file mode 100644 index 0000000..89c3d35 --- /dev/null +++ b/template/src/{{package_name_snake_case}}/__init__.py @@ -0,0 +1 @@ +"""Module containing all source code.""" diff --git a/src/PACKAGE-NAME/__init__.py b/template/src/{{package_name_snake_case}}/py.typed similarity index 100% rename from src/PACKAGE-NAME/__init__.py rename to template/src/{{package_name_snake_case}}/py.typed diff --git a/template/{{_copier_conf.answers_file}}.jinja b/template/{{_copier_conf.answers_file}}.jinja new file mode 100644 index 0000000..a8c521e --- /dev/null +++ b/template/{{_copier_conf.answers_file}}.jinja @@ -0,0 +1,2 @@ +# Changes here will be overwritten by Copier; NEVER EDIT MANUALLY +{{ dict(_copier_answers, copyright_year=copyright_year) | to_nice_yaml -}} From 9c68f25ce4f39ee5cbeb295416d1d6e13a911d88 Mon Sep 17 00:00:00 2001 From: martonvago Date: Tue, 5 Aug 2025 13:12:24 +0100 Subject: [PATCH 02/30] docs: :memo: edit index page --- template/index.qmd.jinja | 2 -- 1 file changed, 2 deletions(-) diff --git a/template/index.qmd.jinja b/template/index.qmd.jinja index d567c08..2eec46c 100644 --- a/template/index.qmd.jinja +++ b/template/index.qmd.jinja @@ -1,5 +1,3 @@ --- title: "Welcome to {{ 'Seedcase ' ~ (seedcase_short_name | title) if is_seedcase_project else package_name }}!" --- - -{{ "{{< include /docs/includes/_wip.qmd >}}" }} From b75f8f90c8d469331996235821df221a68030ee7 Mon Sep 17 00:00:00 2001 From: martonvago Date: Tue, 5 Aug 2025 15:51:51 +0100 Subject: [PATCH 03/30] build: :wrench: update justfile --- .vscode/settings.json | 1 + justfile | 4 ++-- .../{README.md.jinja => README.qmd.jinja} | 0 template/{justfile => justfile.jinja} | 23 +++++++++++++++++-- template/tools/get-contributors.sh | 18 +++++++++++++++ 5 files changed, 42 insertions(+), 4 deletions(-) rename template/{README.md.jinja => README.qmd.jinja} (100%) rename template/{justfile => justfile.jinja} (78%) create mode 100644 template/tools/get-contributors.sh diff --git a/.vscode/settings.json b/.vscode/settings.json index fc0bb11..6ec6d96 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -30,6 +30,7 @@ "python.languageServer": "Pylance", "files.insertFinalNewline": true, "files.associations": { + "justfile.jinja": "django-txt", "*.yml.jinja": "jinja-yaml", "*.cff.jinja": "jinja-yaml", "*.toml.jinja": "jinja-toml", diff --git a/justfile b/justfile index e121875..2fc0660 100644 --- a/justfile +++ b/justfile @@ -26,7 +26,7 @@ update-template: mkdir -p template/tools cp tools/get-contributors.sh template/tools/ cp .github/pull_request_template.md template/.github/ - cp .github/workflows/build-website.yml .github/workflows/dependency-review.yml template/.github/workflows/ + cp .github/workflows/dependency-review.yml template/.github/workflows/ # Check the commit messages on the current branch that are not on the main branch check-commits: @@ -118,4 +118,4 @@ build-readme: # Generate a Quarto include file with the contributors build-contributors: - sh ./tools/get-contributors.sh seedcase-project/template-workshop + sh ./tools/get-contributors.sh seedcase-project/template-python-project diff --git a/template/README.md.jinja b/template/README.qmd.jinja similarity index 100% rename from template/README.md.jinja rename to template/README.qmd.jinja diff --git a/template/justfile b/template/justfile.jinja similarity index 78% rename from template/justfile rename to template/justfile.jinja index 279c94f..1e0e4f6 100644 --- a/template/justfile +++ b/template/justfile.jinja @@ -1,8 +1,15 @@ @_default: just --list --unsorted +@_checks: check-python check-unused test-python check-security check-spelling check-commits +@_builds: build-contributors build-website build-readme + # Run all build-related recipes in the justfile -run-all: install-deps format-python check-python check-unused test-python check-security check-spelling check-commits build-website +{%- if is_seedcase_project %} +run-all: install-deps update-quarto-theme format-python _checks _builds +{%- else %} +run-all: install-deps format-python _checks _builds +{%- endif %} # List all TODO items in the repository list-todos: @@ -16,7 +23,11 @@ install-precommit: uvx pre-commit run --all-files # Update versions of pre-commit hooks uvx pre-commit autoupdate - +{% if is_seedcase_project %} +# Update the Quarto seedcase-theme extension +update-quarto-theme: + quarto add seedcase-project/seedcase-theme --no-prompt +{% endif %} # Install Python package dependencies install-deps: uv sync --all-extras --dev @@ -92,3 +103,11 @@ check-unused: # There are some things should be ignored though, with the allowlist. # Create an allowlist with `vulture --make-allowlist` uv run vulture src/ tests/ **/vulture-allowlist.py + +# Re-build the README file from the Quarto version +build-readme: + uvx --from quarto quarto render README.qmd --to gfm + +# Generate a Quarto include file with the contributors +build-contributors: + sh ./tools/get-contributors.sh {{ package_github_repo }} diff --git a/template/tools/get-contributors.sh b/template/tools/get-contributors.sh new file mode 100644 index 0000000..65bfbb4 --- /dev/null +++ b/template/tools/get-contributors.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +# Get a list of contributors to this repository and save it to +# _contributors.qmd.tmp file. It also: +# +# - Formats users into Markdown links to their GitHub profiles. +# - Removes any usernames with the word "bot" in them. +# - Removes the trailing comma from the list. +repo_spec=${1} +echo "These are the people who have contributed by submitting changes through pull requests :tada:\n\n" > _contributors.qmd.tmp +gh api \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + /repos/$repo_spec/contributors \ + --template '{{range .}} [\@{{.login}}]({{.html_url}}){{"\n"}}{{end}}' | \ + grep -v "\[bot\]" | \ + tr '\n' ', ' | \ + sed -e 's/,$//' >> _contributors.qmd.tmp From 6a604818ec4d4f4fdab610f7f828ab315a875be9 Mon Sep 17 00:00:00 2001 From: martonvago Date: Tue, 5 Aug 2025 15:58:53 +0100 Subject: [PATCH 04/30] build: :wrench: use just recipe in copier task --- copier.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/copier.yaml b/copier.yaml index 38e0de0..5267c6f 100644 --- a/copier.yaml +++ b/copier.yaml @@ -6,7 +6,7 @@ _tasks: - command: "git init -b main && uv add --dev pre-commit ruff typos pytest bandit commitizen genbadge jupyter pytest-cov quartodoc types-tabulate mypy vulture" when: "{{ _copier_operation == 'copy' }}" # If Seedcase project, add seedcase-theme extension - - command: "uv run quarto add --no-prompt seedcase-project/seedcase-theme" + - command: "just update-quarto-theme" when: "{{ _copier_operation == 'copy' and is_seedcase_project }}" # If Seedcase project, use seedcase-theme as project type - command: >- From a6585eba1b26823fd6a5c4c46792c78e4fc445f7 Mon Sep 17 00:00:00 2001 From: martonvago Date: Tue, 5 Aug 2025 16:10:19 +0100 Subject: [PATCH 05/30] build: :wrench: update justfile --- justfile | 12 +++++++----- template/justfile.jinja | 5 +++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/justfile b/justfile index 2fc0660..2e96a02 100644 --- a/justfile +++ b/justfile @@ -2,10 +2,12 @@ just --list --unsorted @_checks: check-spelling check-commits +# Test Seedcase and non-Seedcase projects +@_tests: (test "true") (test "false") @_builds: build-contributors build-website build-readme # Run all build-related recipes in the justfile -run-all: update-quarto-theme update-template _checks test _builds +run-all: update-quarto-theme update-template _checks _tests _builds # Install the pre-commit hooks install-precommit: @@ -45,10 +47,10 @@ check-spelling: uvx typos # Test and check that a Python package can be created from the template -test: +test is_seedcase_project: #!/bin/zsh test_name="test-python-package" - test_dir="$(pwd)/_temp/$test_name" + test_dir="$(pwd)/_temp/{{ is_seedcase_project }}/$test_name" template_dir="$(pwd)" commit=$(git rev-parse HEAD) rm -rf $test_dir @@ -59,7 +61,7 @@ test: --trust \ --data github_user="first-last" \ --data package_name=$test_name \ - --data is_seedcase_project=true \ + --data is_seedcase_project={{ is_seedcase_project }} \ --data author_given_name="First" \ --data author_family_name="Last" \ --data author_email="first.last@example.com" \ @@ -95,7 +97,7 @@ test: --overwrite \ --data github_user="first-last" \ --data package_name=$test_name \ - --data is_seedcase_project=true \ + --data is_seedcase_project={{ is_seedcase_project }} \ --data author_given_name="First" \ --data author_family_name="Last" \ --data author_email="first.last@example.com" \ diff --git a/template/justfile.jinja b/template/justfile.jinja index 1e0e4f6..e0db7b2 100644 --- a/template/justfile.jinja +++ b/template/justfile.jinja @@ -2,13 +2,14 @@ just --list --unsorted @_checks: check-python check-unused test-python check-security check-spelling check-commits +@_tests: test-python @_builds: build-contributors build-website build-readme # Run all build-related recipes in the justfile {%- if is_seedcase_project %} -run-all: install-deps update-quarto-theme format-python _checks _builds +run-all: install-deps update-quarto-theme format-python _checks _tests _builds {%- else %} -run-all: install-deps format-python _checks _builds +run-all: install-deps format-python _checks _tests _builds {%- endif %} # List all TODO items in the repository From c3b8a6027e21ec310c1e543b04e316607bb3fbcf Mon Sep 17 00:00:00 2001 From: martonvago Date: Tue, 5 Aug 2025 16:11:14 +0100 Subject: [PATCH 06/30] test: preparing to recopy from the template --- .cz.toml | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 .cz.toml diff --git a/.cz.toml b/.cz.toml deleted file mode 100644 index ff8c8fb..0000000 --- a/.cz.toml +++ /dev/null @@ -1,6 +0,0 @@ -[tool.commitizen] -bump_message = "build(version): :bookmark: update version from $current_version to $new_version" -update_changelog_on_bump = true -version_provider = "uv" -# Don't regenerate the changelog on every update -changelog_incremental = true From eccca84266f20f4ab95def607965f720f18c3ba5 Mon Sep 17 00:00:00 2001 From: martonvago Date: Tue, 5 Aug 2025 16:11:15 +0100 Subject: [PATCH 07/30] test: preparing to copy onto an existing package --- LICENSE.md | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 LICENSE.md diff --git a/LICENSE.md b/LICENSE.md deleted file mode 100644 index aeed825..0000000 --- a/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -# MIT License - -Copyright (c) 2023-2025 Aarhus University - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. From 3f9094006fdf446140f754f32742dbfe6c6cb066 Mon Sep 17 00:00:00 2001 From: martonvago Date: Tue, 5 Aug 2025 16:22:25 +0100 Subject: [PATCH 08/30] docs: :memo: build README.md from .qmd --- template/README.md.jinja | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 template/README.md.jinja diff --git a/template/README.md.jinja b/template/README.md.jinja new file mode 100644 index 0000000..52ae523 --- /dev/null +++ b/template/README.md.jinja @@ -0,0 +1,5 @@ + + +# {{ package_name }} + + From 07738016f00d7682210dfa39f1dacb15cae970b4 Mon Sep 17 00:00:00 2001 From: martonvago Date: Tue, 5 Aug 2025 16:27:05 +0100 Subject: [PATCH 09/30] docs: :memo: tweak post-copy message --- copier.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/copier.yaml b/copier.yaml index 5267c6f..d53e5f3 100644 --- a/copier.yaml +++ b/copier.yaml @@ -39,7 +39,7 @@ _message_after_copy: | [guide](https://guidebook.seedcase-project.org/operations/security#using-github-apps-to-generate-tokens): - Install the [auto-release-token](https://github.com/apps/auto-release-token) GitHub App - - Create these secrets: UPDATE_VERSION_TOKEN, ADD_TO_BOARD, NETLIFY_AUTH_TOKEN + - Create these secrets: UPDATE_VERSION_TOKEN, ADD_TO_BOARD, NETLIFY_AUTH_TOKEN (if using Netlify) - Create these variables: UPDATE_VERSION_APP_ID, ADD_TO_BOARD_APP_ID 5. List and complete all TODO items in the repository: From c8e797404923f08c39024a66de3f9ec4458c6b15 Mon Sep 17 00:00:00 2001 From: martonvago Date: Tue, 5 Aug 2025 16:29:00 +0100 Subject: [PATCH 10/30] docs: :memo: remove TODO from README.md --- template/README.md.jinja | 1 - 1 file changed, 1 deletion(-) diff --git a/template/README.md.jinja b/template/README.md.jinja index 52ae523..d57964e 100644 --- a/template/README.md.jinja +++ b/template/README.md.jinja @@ -2,4 +2,3 @@ # {{ package_name }} - From c72d8048b96fe8a488d5b7730d90ae0a49772684 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 5 Aug 2025 15:34:54 +0000 Subject: [PATCH 11/30] chore(pre-commit): :pencil2: automatic fixes --- copier.yaml | 2 +- template/README.md.jinja | 1 - template/_quarto.yml.jinja | 4 ++-- template/justfile.jinja | 6 +++--- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/copier.yaml b/copier.yaml index d53e5f3..84c6838 100644 --- a/copier.yaml +++ b/copier.yaml @@ -88,7 +88,7 @@ seedcase_short_name: homepage: type: str help: "What is the homepage of your project?" - default: "{{ 'https://%s.seedcase-project.org' % seedcase_short_name if is_seedcase_project else '' }}" + default: "{{ 'https://%s.seedcase-project.org' % seedcase_short_name if is_seedcase_project else '' }}" author_given_name: type: str diff --git a/template/README.md.jinja b/template/README.md.jinja index d57964e..ba17175 100644 --- a/template/README.md.jinja +++ b/template/README.md.jinja @@ -1,4 +1,3 @@ # {{ package_name }} - diff --git a/template/_quarto.yml.jinja b/template/_quarto.yml.jinja index ce79abd..9333a7a 100644 --- a/template/_quarto.yml.jinja +++ b/template/_quarto.yml.jinja @@ -21,7 +21,7 @@ website: # TODO: add logo logo: "" logo-alt: "{{ package_name }} logo: Main page" - {%- endif %} + {%- endif %} left: - text: "Guide" href: docs/guide/index.qmd @@ -65,7 +65,7 @@ format: seedcase-theme-html: include-before-body: - "docs/site-counter.html" -{%- endif %} +{%- endif %} editor: markdown: diff --git a/template/justfile.jinja b/template/justfile.jinja index e0db7b2..cde9811 100644 --- a/template/justfile.jinja +++ b/template/justfile.jinja @@ -8,9 +8,9 @@ # Run all build-related recipes in the justfile {%- if is_seedcase_project %} run-all: install-deps update-quarto-theme format-python _checks _tests _builds -{%- else %} +{%- else %} run-all: install-deps format-python _checks _tests _builds -{%- endif %} +{%- endif %} # List all TODO items in the repository list-todos: @@ -28,7 +28,7 @@ install-precommit: # Update the Quarto seedcase-theme extension update-quarto-theme: quarto add seedcase-project/seedcase-theme --no-prompt -{% endif %} +{% endif %} # Install Python package dependencies install-deps: uv sync --all-extras --dev From 865a4c50980bfe53b22ff3ae17197746bc84d1f7 Mon Sep 17 00:00:00 2001 From: martonvago Date: Tue, 5 Aug 2025 17:33:49 +0100 Subject: [PATCH 12/30] fix: :bug: add back files that disappeared --- .cz.toml | 6 ++++++ LICENSE.md | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 .cz.toml create mode 100644 LICENSE.md diff --git a/.cz.toml b/.cz.toml new file mode 100644 index 0000000..ff8c8fb --- /dev/null +++ b/.cz.toml @@ -0,0 +1,6 @@ +[tool.commitizen] +bump_message = "build(version): :bookmark: update version from $current_version to $new_version" +update_changelog_on_bump = true +version_provider = "uv" +# Don't regenerate the changelog on every update +changelog_incremental = true diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..aeed825 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +# MIT License + +Copyright (c) 2023-2025 Aarhus University + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From a4065508b7c7d6f71fd089a3eadf9c7db83ec25e Mon Sep 17 00:00:00 2001 From: martonvago Date: Tue, 5 Aug 2025 17:47:58 +0100 Subject: [PATCH 13/30] refactor: :recycle: always have goat counter --- template/_quarto.yml.jinja | 5 ++--- template/docs/site-counter.html.jinja | 3 +++ ... if seedcase_project %}site-counter.html{% endif %}.jinja | 3 --- 3 files changed, 5 insertions(+), 6 deletions(-) create mode 100644 template/docs/site-counter.html.jinja delete mode 100644 template/docs/{% if seedcase_project %}site-counter.html{% endif %}.jinja diff --git a/template/_quarto.yml.jinja b/template/_quarto.yml.jinja index 9333a7a..b79e8ad 100644 --- a/template/_quarto.yml.jinja +++ b/template/_quarto.yml.jinja @@ -60,12 +60,11 @@ quartodoc: metadata-files: - docs/reference/_sidebar.yml -{% if is_seedcase_project %} + format: - seedcase-theme-html: + {{ "seedcase-theme-html" if is_seedcase_project else "html" }}: include-before-body: - "docs/site-counter.html" -{%- endif %} editor: markdown: diff --git a/template/docs/site-counter.html.jinja b/template/docs/site-counter.html.jinja new file mode 100644 index 0000000..b92291e --- /dev/null +++ b/template/docs/site-counter.html.jinja @@ -0,0 +1,3 @@ + + diff --git a/template/docs/{% if seedcase_project %}site-counter.html{% endif %}.jinja b/template/docs/{% if seedcase_project %}site-counter.html{% endif %}.jinja deleted file mode 100644 index 5156b87..0000000 --- a/template/docs/{% if seedcase_project %}site-counter.html{% endif %}.jinja +++ /dev/null @@ -1,3 +0,0 @@ - - From 694508f99a79f11b090ed419a75d260c84b9d922 Mon Sep 17 00:00:00 2001 From: martonvago <57952344+martonvago@users.noreply.github.com> Date: Wed, 6 Aug 2025 11:11:30 +0100 Subject: [PATCH 14/30] refactor: :recycle: apply suggestions from code review Co-authored-by: Luke W. Johnston --- copier.yaml | 4 ++-- justfile | 2 -- template/.github/CODEOWNERS.jinja | 10 ---------- template/.github/dependabot.yml.jinja | 2 +- template/_quarto.yml.jinja | 3 ++- template/index.qmd.jinja | 2 +- template/justfile.jinja | 2 +- template/pyproject.toml.jinja | 8 -------- 8 files changed, 7 insertions(+), 26 deletions(-) diff --git a/copier.yaml b/copier.yaml index 84c6838..10106a2 100644 --- a/copier.yaml +++ b/copier.yaml @@ -3,7 +3,7 @@ _subdirectory: template # Post-copy commands: _tasks: # Add dev dependencies - - command: "git init -b main && uv add --dev pre-commit ruff typos pytest bandit commitizen genbadge jupyter pytest-cov quartodoc types-tabulate mypy vulture" + - command: "git init -b main; uv add --dev pre-commit ruff typos pytest bandit commitizen genbadge jupyter pytest-cov quartodoc types-tabulate mypy vulture" when: "{{ _copier_operation == 'copy' }}" # If Seedcase project, add seedcase-theme extension - command: "just update-quarto-theme" @@ -109,7 +109,7 @@ review_team: github_board_number: type: str - help: "What is the number of the GitHub project board to add issues and PRs to?" + help: "What is the GitHub project board number to add issues and PRs to?" validator: | {% if github_board_number and not github_board_number.isdigit() %} The board number must be an integer. diff --git a/justfile b/justfile index 2e96a02..d6d658a 100644 --- a/justfile +++ b/justfile @@ -60,7 +60,6 @@ test is_seedcase_project: --defaults \ --trust \ --data github_user="first-last" \ - --data package_name=$test_name \ --data is_seedcase_project={{ is_seedcase_project }} \ --data author_given_name="First" \ --data author_family_name="Last" \ @@ -96,7 +95,6 @@ test is_seedcase_project: --trust \ --overwrite \ --data github_user="first-last" \ - --data package_name=$test_name \ --data is_seedcase_project={{ is_seedcase_project }} \ --data author_given_name="First" \ --data author_family_name="Last" \ diff --git a/template/.github/CODEOWNERS.jinja b/template/.github/CODEOWNERS.jinja index 172a7e0..bad0bef 100644 --- a/template/.github/CODEOWNERS.jinja +++ b/template/.github/CODEOWNERS.jinja @@ -1,13 +1,3 @@ # All members on Developers team get added to review PRs * {{ review_team }} -# Ignore these so we don't get added to sync PRs -/.github/ -/.vscode/ -/.devcontainer/ -justfile -.editorconfig -.gitignore -ruff.toml -pyproject.toml -uv.lock diff --git a/template/.github/dependabot.yml.jinja b/template/.github/dependabot.yml.jinja index 76c25b2..627835e 100644 --- a/template/.github/dependabot.yml.jinja +++ b/template/.github/dependabot.yml.jinja @@ -1,6 +1,6 @@ version: 2 updates: - - package-ecosystem: pip + - package-ecosystem: uv directory: / schedule: interval: monthly diff --git a/template/_quarto.yml.jinja b/template/_quarto.yml.jinja index b79e8ad..dba6b7d 100644 --- a/template/_quarto.yml.jinja +++ b/template/_quarto.yml.jinja @@ -7,7 +7,8 @@ project: - "index.qmd" website: - title: "{{ 'Seedcase ' ~ (seedcase_short_name | title) if is_seedcase_project else package_name }}" + # TODO: Fill in the title of the website. + title: "" site-url: "{{ homepage }}" repo-url: "https://github.com/{{ package_github_repo }}" page-navigation: true diff --git a/template/index.qmd.jinja b/template/index.qmd.jinja index 2eec46c..2769a9f 100644 --- a/template/index.qmd.jinja +++ b/template/index.qmd.jinja @@ -1,3 +1,3 @@ --- -title: "Welcome to {{ 'Seedcase ' ~ (seedcase_short_name | title) if is_seedcase_project else package_name }}!" +title: "Welcome!" --- diff --git a/template/justfile.jinja b/template/justfile.jinja index cde9811..7f4a1dc 100644 --- a/template/justfile.jinja +++ b/template/justfile.jinja @@ -1,7 +1,7 @@ @_default: just --list --unsorted -@_checks: check-python check-unused test-python check-security check-spelling check-commits +@_checks: check-python check-unused check-security check-spelling check-commits @_tests: test-python @_builds: build-contributors build-website build-readme diff --git a/template/pyproject.toml.jinja b/template/pyproject.toml.jinja index 7ae59ce..a12e4c8 100644 --- a/template/pyproject.toml.jinja +++ b/template/pyproject.toml.jinja @@ -28,11 +28,3 @@ issues = "https://github.com/{{ package_github_repo }}/issues" [build-system] requires = ["hatchling"] build-backend = "hatchling.build" - -[tool.pytest.ini_options] -addopts = [ - # A short traceback mode to make it easier to view - "--tb=short", - # Use the `src/` package - "--import-mode=importlib", -] From 88fc9be7e53aef10056cc8a0a6c6484147dc6fcc Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 6 Aug 2025 10:12:37 +0000 Subject: [PATCH 15/30] chore(pre-commit): :pencil2: automatic fixes --- template/.github/CODEOWNERS.jinja | 1 - 1 file changed, 1 deletion(-) diff --git a/template/.github/CODEOWNERS.jinja b/template/.github/CODEOWNERS.jinja index bad0bef..9681e53 100644 --- a/template/.github/CODEOWNERS.jinja +++ b/template/.github/CODEOWNERS.jinja @@ -1,3 +1,2 @@ # All members on Developers team get added to review PRs * {{ review_team }} - From 4ce030f829bb2830b4ca9247d7e293101d59b583 Mon Sep 17 00:00:00 2001 From: martonvago Date: Wed, 6 Aug 2025 11:19:17 +0100 Subject: [PATCH 16/30] refactor: :recycle: do not auto-add seedcase-theme --- copier.yaml | 8 -------- docs/guide.qmd | 2 ++ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/copier.yaml b/copier.yaml index 84c6838..bb3be03 100644 --- a/copier.yaml +++ b/copier.yaml @@ -5,14 +5,6 @@ _tasks: # Add dev dependencies - command: "git init -b main && uv add --dev pre-commit ruff typos pytest bandit commitizen genbadge jupyter pytest-cov quartodoc types-tabulate mypy vulture" when: "{{ _copier_operation == 'copy' }}" - # If Seedcase project, add seedcase-theme extension - - command: "just update-quarto-theme" - when: "{{ _copier_operation == 'copy' and is_seedcase_project }}" - # If Seedcase project, use seedcase-theme as project type - - command: >- - uv run python -c "from pathlib import Path; file = Path('_quarto.yml'); file.write_text(file.read_text().replace('type: website', 'type: seedcase-theme', 1))" - when: "{{ _copier_operation == 'copy' and is_seedcase_project }}" - # Message to show after generating or regenerating the project successfully _message_after_copy: | diff --git a/docs/guide.qmd b/docs/guide.qmd index c1c60fb..57c42a3 100644 --- a/docs/guide.qmd +++ b/docs/guide.qmd @@ -136,6 +136,8 @@ Project, run: just update-quarto-theme ``` +Then set `seedcase-theme` as your project `type` in `_quarto.yml`. + This adds the `seedcase-theme` Quarto theme to the website, which provides a consistent look and feel across all Seedcase Project websites, including for Python package websites. From becdbe4e80a3b3c97c4de90eada62c48e978b013 Mon Sep 17 00:00:00 2001 From: martonvago Date: Wed, 6 Aug 2025 11:24:46 +0100 Subject: [PATCH 17/30] docs: :memo: tweak post-install message --- copier.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/copier.yaml b/copier.yaml index f4e5b01..91be0e3 100644 --- a/copier.yaml +++ b/copier.yaml @@ -30,9 +30,10 @@ _message_after_copy: | 4. Configure GitHub following this [guide](https://guidebook.seedcase-project.org/operations/security#using-github-apps-to-generate-tokens): - - Install the [auto-release-token](https://github.com/apps/auto-release-token) GitHub App - - Create these secrets: UPDATE_VERSION_TOKEN, ADD_TO_BOARD, NETLIFY_AUTH_TOKEN (if using Netlify) - - Create these variables: UPDATE_VERSION_APP_ID, ADD_TO_BOARD_APP_ID + - Install the [auto-release-token](https://github.com/apps/auto-release-token) + and [add-to-board-token](https://github.com/apps/add-to-board-token) GitHub Apps + - Create an `UPDATE_VERSION_TOKEN` and `ADD_TO_BOARD_TOKEN` secret for the GitHub Apps + - Create an `UPDATE_VERSION_APP_ID` and `ADD_TO_BOARD_APP_ID` variable of the GitHub Apps' IDs 5. List and complete all TODO items in the repository: From 02181b8d9c77b05310d9834cc8d27c75d44ac1c2 Mon Sep 17 00:00:00 2001 From: martonvago Date: Wed, 6 Aug 2025 11:26:08 +0100 Subject: [PATCH 18/30] chore: :wrench: change justfile.jinja file association --- .vscode/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 6ec6d96..346d266 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -30,7 +30,7 @@ "python.languageServer": "Pylance", "files.insertFinalNewline": true, "files.associations": { - "justfile.jinja": "django-txt", + "justfile.jinja": "plaintext", "*.yml.jinja": "jinja-yaml", "*.cff.jinja": "jinja-yaml", "*.toml.jinja": "jinja-toml", From 471e8c3438f7688dfed7e170cf91c00b47b03b15 Mon Sep 17 00:00:00 2001 From: martonvago Date: Wed, 6 Aug 2025 11:35:28 +0100 Subject: [PATCH 19/30] refactor: :recycle: extract github_user from package_github_repo --- copier.yaml | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/copier.yaml b/copier.yaml index 91be0e3..bfe6617 100644 --- a/copier.yaml +++ b/copier.yaml @@ -40,14 +40,20 @@ _message_after_copy: | $ just list-todos # Questions: -github_user: +package_github_repo: type: str - help: "What is the GitHub username of the person or organisation who owns the package?" + help: "What is or will be the GitHub repository spec for the project?" + placeholder: "user/repo" validator: | - {% if github_user and not (github_user | regex_search('^[\w.-]+$')) %} - Must contain only alphanumeric characters and `_`, `-`, or `.`. + {% if package_github_repo and not (package_github_repo | regex_search('^[\w.-]+\/[\w.-]+$')) %} + Must be in the format `user/repo` and contain only alphanumeric characters and `_`, `-`, or `.`. {% endif %} +github_user: + type: str + default: "{{ package_github_repo.split('/')[0] if package_github_repo else '' }}" + when: false + package_name: type: str help: "What is the name of the package?" @@ -62,11 +68,6 @@ package_name_snake_case: default: "{{package_name | replace('-', '_') | replace('.', '_')}}" when: false -package_github_repo: - type: str - default: "{{ github_user ~ '/' ~ package_name }}" - when: false - is_seedcase_project: type: bool help: "Is this package part of the Seedcase Project?" From 431f2a405fabe9cafc07676abf553b5e1537c806 Mon Sep 17 00:00:00 2001 From: martonvago Date: Wed, 6 Aug 2025 11:39:24 +0100 Subject: [PATCH 20/30] refactor: :recycle: remove seedcase_short_name --- copier.yaml | 8 +------- template/_quarto.yml.jinja | 4 ++-- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/copier.yaml b/copier.yaml index bfe6617..92ad684 100644 --- a/copier.yaml +++ b/copier.yaml @@ -73,16 +73,10 @@ is_seedcase_project: help: "Is this package part of the Seedcase Project?" default: "{{ github_user == 'seedcase-project' }}" -seedcase_short_name: - type: str - help: "What is the short name of the package?" - default: "{{ package_name[9:] if ('seedcase-' in package_name) else '' }}" - when: "{{ is_seedcase_project }}" - homepage: type: str help: "What is the homepage of your project?" - default: "{{ 'https://%s.seedcase-project.org' % seedcase_short_name if is_seedcase_project else '' }}" + default: "{{ 'https://%s.seedcase-project.org' % package_name if is_seedcase_project else '' }}" author_given_name: type: str diff --git a/template/_quarto.yml.jinja b/template/_quarto.yml.jinja index dba6b7d..70efacc 100644 --- a/template/_quarto.yml.jinja +++ b/template/_quarto.yml.jinja @@ -16,8 +16,8 @@ website: pinned: true title: false {%- if is_seedcase_project %} - logo: "_extensions/seedcase-project/seedcase-theme/logos/navbar-logo-seedcase-{{ seedcase_short_name }}.svg" - logo-alt: "Seedcase {{ seedcase_short_name | title }} logo: Main page" + logo: "_extensions/seedcase-project/seedcase-theme/logos/navbar-logo-{{ package_name }}.svg" + logo-alt: "{{ package_name }} logo: Main page" {%- else %} # TODO: add logo logo: "" From ab59e84f44fab177d7f5e1e2fc7bc2db900d537f Mon Sep 17 00:00:00 2001 From: martonvago Date: Wed, 6 Aug 2025 11:41:33 +0100 Subject: [PATCH 21/30] refactor: :recycle: do not template PR assignee --- copier.yaml | 4 ---- justfile | 6 ++---- template/.github/{dependabot.yml.jinja => dependabot.yml} | 4 ---- 3 files changed, 2 insertions(+), 12 deletions(-) rename template/.github/{dependabot.yml.jinja => dependabot.yml} (67%) diff --git a/copier.yaml b/copier.yaml index 92ad684..7bcd79b 100644 --- a/copier.yaml +++ b/copier.yaml @@ -107,7 +107,3 @@ copyright_year: type: str default: "{{ copyright_year | default('%Y' | strftime) }}" when: false - -dependabot_pr_assignee: - type: str - help: "What is the GitHub username of the person to assign to PRs opened by dependabot?" diff --git a/justfile b/justfile index d6d658a..8d523a3 100644 --- a/justfile +++ b/justfile @@ -65,8 +65,7 @@ test is_seedcase_project: --data author_family_name="Last" \ --data author_email="first.last@example.com" \ --data review_team="@first-last/developers" \ - --data github_board_number=22 \ - --data dependabot_pr_assignee="mango90" + --data github_board_number=22 # Run checks in the generated test Python package cd $test_dir git add . @@ -100,8 +99,7 @@ test is_seedcase_project: --data author_family_name="Last" \ --data author_email="first.last@example.com" \ --data review_team="@first-last/developers" \ - --data github_board_number=22 \ - --data dependabot_pr_assignee="mango90" + --data github_board_number=22 # Clean up any leftover and temporary build files cleanup: diff --git a/template/.github/dependabot.yml.jinja b/template/.github/dependabot.yml similarity index 67% rename from template/.github/dependabot.yml.jinja rename to template/.github/dependabot.yml index 627835e..3a50f8a 100644 --- a/template/.github/dependabot.yml.jinja +++ b/template/.github/dependabot.yml @@ -8,7 +8,3 @@ updates: commit-message: prefix: build include: scope -{%- if dependabot_pr_assignee %} - assignees: - - "{{ dependabot_pr_assignee }}" -{% endif %} From a0b401e38a2591825a9ec2bcdeb43a133235568e Mon Sep 17 00:00:00 2001 From: martonvago Date: Wed, 6 Aug 2025 11:52:35 +0100 Subject: [PATCH 22/30] refactor: :recycle: make house icon Seedcase-only --- template/_quarto.yml.jinja | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/template/_quarto.yml.jinja b/template/_quarto.yml.jinja index 70efacc..751e1a5 100644 --- a/template/_quarto.yml.jinja +++ b/template/_quarto.yml.jinja @@ -32,9 +32,11 @@ website: - icon: github href: "https://github.com/{{ package_github_repo }}" aria-label: "GitHub icon: Source code" + {% if is_seedcase_project -%} - icon: house - href: "{{ 'https://seedcase-project.org' if is_seedcase_project else homepage }}" - aria-label: "House icon: {{ 'Seedcase Project' if is_seedcase_project else package_name }} home page" + href: "https://seedcase-project.org" + aria-label: "House icon: Main website for the Seedcase Project" + {% endif %} sidebar: - id: design pinned: true From 2bb14f04cfd72ad3d2db9e25d9bc2479e4fbfa90 Mon Sep 17 00:00:00 2001 From: martonvago Date: Wed, 6 Aug 2025 11:55:10 +0100 Subject: [PATCH 23/30] chore: :truck: remove .jinja from index file --- template/{index.qmd.jinja => index.qmd} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename template/{index.qmd.jinja => index.qmd} (100%) diff --git a/template/index.qmd.jinja b/template/index.qmd similarity index 100% rename from template/index.qmd.jinja rename to template/index.qmd From 99e456a8448e26b77dcdcc912871ad974119b246 Mon Sep 17 00:00:00 2001 From: martonvago Date: Wed, 6 Aug 2025 11:55:53 +0100 Subject: [PATCH 24/30] build: :wrench: add recipes to justfile --- template/justfile.jinja | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/template/justfile.jinja b/template/justfile.jinja index 7f4a1dc..ab72553 100644 --- a/template/justfile.jinja +++ b/template/justfile.jinja @@ -112,3 +112,11 @@ build-readme: # Generate a Quarto include file with the contributors build-contributors: sh ./tools/get-contributors.sh {{ package_github_repo }} + +# Check for and apply updates from the template +update-from-template: + uvx copier update --trust --defaults + +# Reset repo changes to match the template +reset-from-template: + uvx copier recopy --trust --defaults From e34cc61b57871bb443cb2bd7e9490c6c86651ede Mon Sep 17 00:00:00 2001 From: martonvago Date: Wed, 6 Aug 2025 11:56:20 +0100 Subject: [PATCH 25/30] test: preparing to recopy from the template --- .cz.toml | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 .cz.toml diff --git a/.cz.toml b/.cz.toml deleted file mode 100644 index ff8c8fb..0000000 --- a/.cz.toml +++ /dev/null @@ -1,6 +0,0 @@ -[tool.commitizen] -bump_message = "build(version): :bookmark: update version from $current_version to $new_version" -update_changelog_on_bump = true -version_provider = "uv" -# Don't regenerate the changelog on every update -changelog_incremental = true From 1184ed27e7ccaf3111ff02a32008d4f74d0f636d Mon Sep 17 00:00:00 2001 From: martonvago Date: Wed, 6 Aug 2025 11:56:20 +0100 Subject: [PATCH 26/30] test: preparing to copy onto an existing package --- LICENSE.md | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 LICENSE.md diff --git a/LICENSE.md b/LICENSE.md deleted file mode 100644 index aeed825..0000000 --- a/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -# MIT License - -Copyright (c) 2023-2025 Aarhus University - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. From 28b072ae32144f0744aa2b18923fa7c8397cd335 Mon Sep 17 00:00:00 2001 From: martonvago Date: Wed, 6 Aug 2025 12:02:03 +0100 Subject: [PATCH 27/30] fix: :bug: fix copier test --- .cz.toml | 6 ++++++ justfile | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 .cz.toml diff --git a/.cz.toml b/.cz.toml new file mode 100644 index 0000000..ff8c8fb --- /dev/null +++ b/.cz.toml @@ -0,0 +1,6 @@ +[tool.commitizen] +bump_message = "build(version): :bookmark: update version from $current_version to $new_version" +update_changelog_on_bump = true +version_provider = "uv" +# Don't regenerate the changelog on every update +changelog_incremental = true diff --git a/justfile b/justfile index 8d523a3..9fdf690 100644 --- a/justfile +++ b/justfile @@ -59,7 +59,7 @@ test is_seedcase_project: --vcs-ref=$commit \ --defaults \ --trust \ - --data github_user="first-last" \ + --data package_github_repo="first-last/repo" \ --data is_seedcase_project={{ is_seedcase_project }} \ --data author_given_name="First" \ --data author_family_name="Last" \ @@ -93,7 +93,7 @@ test is_seedcase_project: --defaults \ --trust \ --overwrite \ - --data github_user="first-last" \ + --data package_github_repo="first-last/repo" \ --data is_seedcase_project={{ is_seedcase_project }} \ --data author_given_name="First" \ --data author_family_name="Last" \ From 267be141639ce0e8186f551d5acd675d790b780d Mon Sep 17 00:00:00 2001 From: martonvago Date: Wed, 6 Aug 2025 12:08:53 +0100 Subject: [PATCH 28/30] fix: :bug: add back LICENSE --- LICENSE.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE.md diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..aeed825 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +# MIT License + +Copyright (c) 2023-2025 Aarhus University + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 4d0a3f4f1ec3608088720a42f55ac185f647943d Mon Sep 17 00:00:00 2001 From: martonvago Date: Thu, 7 Aug 2025 16:54:41 +0100 Subject: [PATCH 29/30] build: :wrench: use latest get-contributors.sh in template --- template/tools/get-contributors.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/template/tools/get-contributors.sh b/template/tools/get-contributors.sh index 65bfbb4..40aea37 100644 --- a/template/tools/get-contributors.sh +++ b/template/tools/get-contributors.sh @@ -1,13 +1,13 @@ #!/usr/bin/env bash # Get a list of contributors to this repository and save it to -# _contributors.qmd.tmp file. It also: +# _contributors.qmd file (overwritten if it exists). It also: # # - Formats users into Markdown links to their GitHub profiles. # - Removes any usernames with the word "bot" in them. # - Removes the trailing comma from the list. repo_spec=${1} -echo "These are the people who have contributed by submitting changes through pull requests :tada:\n\n" > _contributors.qmd.tmp +echo "These are the people who have contributed by submitting changes through pull requests :tada:\n\n" > _contributors.qmd gh api \ -H "Accept: application/vnd.github+json" \ -H "X-GitHub-Api-Version: 2022-11-28" \ @@ -15,4 +15,4 @@ gh api \ --template '{{range .}} [\@{{.login}}]({{.html_url}}){{"\n"}}{{end}}' | \ grep -v "\[bot\]" | \ tr '\n' ', ' | \ - sed -e 's/,$//' >> _contributors.qmd.tmp + sed -e 's/,$//' >> _contributors.qmd From 5173c990951b3b7faa0a79391fa5b5c568ac6c12 Mon Sep 17 00:00:00 2001 From: "Luke W. Johnston" Date: Fri, 8 Aug 2025 09:16:00 +0200 Subject: [PATCH 30/30] refactor: strip empty jinja lines --- template/_quarto.yml.jinja | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/_quarto.yml.jinja b/template/_quarto.yml.jinja index 751e1a5..cf7c3ab 100644 --- a/template/_quarto.yml.jinja +++ b/template/_quarto.yml.jinja @@ -36,7 +36,7 @@ website: - icon: house href: "https://seedcase-project.org" aria-label: "House icon: Main website for the Seedcase Project" - {% endif %} + {%- endif %} sidebar: - id: design pinned: true