Skip to content

feat: ✨ add files with copier variables #127

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 33 commits into from
Aug 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
a758d44
feat: :sparkles: add files with copier variables to template folder
martonvago Aug 5, 2025
745f84b
Merge branch 'main' into feat/template-variable-files
martonvago Aug 5, 2025
9c68f25
docs: :memo: edit index page
martonvago Aug 5, 2025
a0a8787
Merge branch 'main' into feat/template-variable-files
martonvago Aug 5, 2025
b75f8f9
build: :wrench: update justfile
martonvago Aug 5, 2025
6a60481
build: :wrench: use just recipe in copier task
martonvago Aug 5, 2025
a6585eb
build: :wrench: update justfile
martonvago Aug 5, 2025
c3b8a60
test: preparing to recopy from the template
martonvago Aug 5, 2025
eccca84
test: preparing to copy onto an existing package
martonvago Aug 5, 2025
3f90940
docs: :memo: build README.md from .qmd
martonvago Aug 5, 2025
0773801
docs: :memo: tweak post-copy message
martonvago Aug 5, 2025
c8e7974
docs: :memo: remove TODO from README.md
martonvago Aug 5, 2025
c72d804
chore(pre-commit): :pencil2: automatic fixes
pre-commit-ci[bot] Aug 5, 2025
865a4c5
fix: :bug: add back files that disappeared
martonvago Aug 5, 2025
a406550
refactor: :recycle: always have goat counter
martonvago Aug 5, 2025
694508f
refactor: :recycle: apply suggestions from code review
martonvago Aug 6, 2025
88fc9be
chore(pre-commit): :pencil2: automatic fixes
pre-commit-ci[bot] Aug 6, 2025
4ce030f
refactor: :recycle: do not auto-add seedcase-theme
martonvago Aug 6, 2025
a9aa535
Merge branch 'feat/template-variable-files' of github.com:seedcase-pr…
martonvago Aug 6, 2025
becdbe4
docs: :memo: tweak post-install message
martonvago Aug 6, 2025
02181b8
chore: :wrench: change justfile.jinja file association
martonvago Aug 6, 2025
471e8c3
refactor: :recycle: extract github_user from package_github_repo
martonvago Aug 6, 2025
431f2a4
refactor: :recycle: remove seedcase_short_name
martonvago Aug 6, 2025
ab59e84
refactor: :recycle: do not template PR assignee
martonvago Aug 6, 2025
a0b401e
refactor: :recycle: make house icon Seedcase-only
martonvago Aug 6, 2025
2bb14f0
chore: :truck: remove .jinja from index file
martonvago Aug 6, 2025
99e456a
build: :wrench: add recipes to justfile
martonvago Aug 6, 2025
e34cc61
test: preparing to recopy from the template
martonvago Aug 6, 2025
1184ed2
test: preparing to copy onto an existing package
martonvago Aug 6, 2025
28b072a
fix: :bug: fix copier test
martonvago Aug 6, 2025
267be14
fix: :bug: add back LICENSE
martonvago Aug 6, 2025
4d0a3f4
build: :wrench: use latest get-contributors.sh in template
martonvago Aug 7, 2025
5173c99
refactor: strip empty jinja lines
lwjohnst86 Aug 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
_ignore
bin/
dev/
_temp/

# Temporary files
*.tmp
Expand Down
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"python.languageServer": "Pylance",
"files.insertFinalNewline": true,
"files.associations": {
"justfile.jinja": "plaintext",
"*.yml.jinja": "jinja-yaml",
"*.cff.jinja": "jinja-yaml",
"*.toml.jinja": "jinja-toml",
Expand Down
109 changes: 109 additions & 0 deletions copier.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
_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' }}"

# 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)
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:

$ just list-todos

# Questions:
package_github_repo:
type: str
help: "What is or will be the GitHub repository spec for the project?"
placeholder: "user/repo"
validator: |
{% 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?"
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

is_seedcase_project:
type: bool
help: "Is this package part of the Seedcase Project?"
default: "{{ github_user == 'seedcase-project' }}"

homepage:
type: str
help: "What is the homepage of your project?"
default: "{{ 'https://%s.seedcase-project.org' % package_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 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.
{% endif %}

copyright_year:
type: str
default: "{{ copyright_year | default('%Y' | strftime) }}"
when: false
2 changes: 2 additions & 0 deletions docs/guide.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
64 changes: 58 additions & 6 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -26,7 +28,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:
Expand All @@ -45,9 +47,59 @@ check-spelling:
uvx typos

# Test and check that a Python package can be created from the template
# TODO: add test for copier
test:
echo "copier test"
test is_seedcase_project:
#!/bin/zsh
test_name="test-python-package"
test_dir="$(pwd)/_temp/{{ is_seedcase_project }}/$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 package_github_repo="first-last/repo" \
--data is_seedcase_project={{ is_seedcase_project }} \
--data author_given_name="First" \
--data author_family_name="Last" \
--data author_email="[email protected]" \
--data review_team="@first-last/developers" \
--data github_board_number=22
# 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 package_github_repo="first-last/repo" \
--data is_seedcase_project={{ is_seedcase_project }} \
--data author_given_name="First" \
--data author_family_name="Last" \
--data author_email="[email protected]" \
--data review_team="@first-last/developers" \
--data github_board_number=22

# Clean up any leftover and temporary build files
cleanup:
Expand All @@ -64,4 +116,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
2 changes: 2 additions & 0 deletions template/.github/CODEOWNERS.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# All members on Developers team get added to review PRs
* {{ review_team }}
10 changes: 10 additions & 0 deletions template/.github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: 2
updates:
- package-ecosystem: uv
directory: /
schedule:
interval: monthly
versioning-strategy: increase-if-necessary
commit-message:
prefix: build
include: scope
27 changes: 27 additions & 0 deletions template/.github/workflows/add-to-project.yml.jinja
Original file line number Diff line number Diff line change
@@ -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 }}' }}
24 changes: 24 additions & 0 deletions template/CITATION.cff.jinja
Original file line number Diff line number Diff line change
@@ -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 }}"
21 changes: 21 additions & 0 deletions template/LICENSE.md.jinja
Original file line number Diff line number Diff line change
@@ -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.
3 changes: 3 additions & 0 deletions template/README.md.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@


# {{ package_name }}
3 changes: 3 additions & 0 deletions template/README.qmd.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# {{ package_name }}

<!-- TODO: Add README for project. -->
75 changes: 75 additions & 0 deletions template/_quarto.yml.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
project:
type: website
# Delete auto-generated files from `quartodoc`
post-render: rm -f docs/reference/*.qmd
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that this doesn't work, I think Quarto turns off the use of rm in post-rendering.

render:
- "docs/*"
- "index.qmd"

website:
# TODO: Fill in the title of the website.
title: ""
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-{{ package_name }}.svg"
logo-alt: "{{ package_name }} 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"
{% if is_seedcase_project -%}
- icon: house
href: "https://seedcase-project.org"
aria-label: "House icon: Main website for the Seedcase Project"
{%- endif %}
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

format:
{{ "seedcase-theme-html" if is_seedcase_project else "html" }}:
include-before-body:
- "docs/site-counter.html"

editor:
markdown:
wrap: 72
canonical: true
Loading