Automatically update citation files (CITATION.cff) in a GitHub repository from `pyproject.toml`, GitHub releases, and PyPI releases.
Project description
updateCitation
Automatically update CITATION.cff from your Python project's pyproject.toml, GitHub release data, and PyPI release data.
The easiest setup is one GitHub Actions file. You do not need to install updateCitation on your computer, and you do not need to add anything to pyproject.toml unless you want to change the defaults.
Quick Start
Choose one of these:
| Goal | Best choice | File you create |
|---|---|---|
GitHub updates CITATION.cff after you push a commit. |
GitHub Action | .github/workflows/updateCitation.yml |
Update CITATION.cff on your computer before a commit. |
Git hook |
.git/hooks/pre-commit |
Add updateCitation to an existing pre-commit setup. |
pre-commit hook |
.pre-commit-config.yaml |
Option: GitHub Action
This is the simplest option. It runs on GitHub after you push.
- In the top level of your repository, create a folder named
.github. - Inside
.github, create a folder namedworkflows. - Inside
.github/workflows, create a file namedupdateCitation.yml. - Paste this into
.github/workflows/updateCitation.yml:
name: Update CITATION.cff
on:
push:
workflow_dispatch:
permissions:
contents: write
jobs:
updateCitation:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: '3.13'
- name: Run updateCitation
env:
GITHUB_TOKEN: ${{ github.token }}
run: pipx run updateCitation
- Commit the file and push it to GitHub.
If the default settings work for your project, you are done. You do not need a [tool.updateCitation] section in pyproject.toml.
Option: Run Locally Before Pushing
Running locally means updateCitation runs on your computer before changes are sent to GitHub. You can do this with a plain Git hook or with pre-commit.
Are you using pre-commit?
Look in the top directory of your repository.
- If there is a file named
.pre-commit-config.yaml, your project is usingpre-commit. - If there is no
.pre-commit-config.yaml, your project is probably not usingpre-commityet. - You can also run
pre-commit --versionin a terminal. If it prints a version number, thepre-commitprogram is installed on your computer.
If your project already has .pre-commit-config.yaml, use the pre-commit instructions below. If not, the plain Git hook is usually simpler for one person.
Git Hook
A Git hook runs when you commit. This file is local to your computer and is not uploaded to GitHub.
- In the top directory of your repository, open the hidden
.gitfolder. - Inside
.git, open thehooksfolder. - Create a file named
pre-commit. - Paste this into
.git/hooks/pre-commit:
#!/usr/bin/env bash
set -euo pipefail
pipx run updateCitation
This example uses pipx so updateCitation does not have to be added to your project. If you use uv, replace pipx run updateCitation with uv run updateCitation. If you prefer uvx, replace it with uvx updateCitation.
- On macOS or Linux, make the file executable:
chmod +x .git/hooks/pre-commit
Now each git commit runs updateCitation before finalizing the commit. If updateCitation changes CITATION.cff, review the change, add it with git add CITATION.cff, and commit again.
pre-commit Hook
Use this if your project already uses pre-commit or if you want a shared hook that collaborators can install.
- In the top directory of your repository, create a file named
.pre-commit-config.yaml. - Paste this into
.pre-commit-config.yaml:
repos:
- repo: local
hooks:
- id: updatecitation
name: updateCitation
entry: pipx run updateCitation
language: system
pass_filenames: false
always_run: true
This example uses pipx. If you use uv, change the entry line to entry: uv run updateCitation. If you prefer uvx, change it to entry: uvx updateCitation.
- Install the hook:
pre-commit install
Now each commit runs updateCitation through pre-commit before finalizing the commit.
Which Command Should I Use?
All of these run the same updateCitation script. Use one command style and put that command in your Git hook or pre-commit hook.
| How you manage Python tools | Recommended setup command | Command to run updateCitation |
|---|---|---|
| GitHub Action only | No local setup | pipx run updateCitation |
| uv project | uv add --dev updateCitation |
uv run updateCitation |
| pip project | Add updateCitation to a developer-only optional dependency |
updateCitation from your active virtual environment |
| No project install, pipx available | No project change | pipx run updateCitation |
| No project install, uvx available | No project change | uvx updateCitation |
For uv-managed projects, the recommended local setup is:
uv add --dev updateCitation
Then use this command in your Git hook or pre-commit hook:
uv run updateCitation
For pip-managed projects, add updateCitation to an optional dependency group that only developers install. In pyproject.toml, create or update this section:
[project.optional-dependencies]
developer = [
"updateCitation",
]
Then developers install that group in their virtual environment:
python -m pip install -e ".[developer]"
After that, the installed script is:
updateCitation
For a plain Git hook, use the script inside your virtual environment if the hook cannot find updateCitation. If your virtual environment folder is named .venv, the command is .venv/bin/updateCitation on macOS or Linux and .venv/Scripts/updateCitation.exe on Windows.
At the most basic level, the local choices are:
| Package command | Git hook |
pre-commit hook |
|---|---|---|
uv run updateCitation |
yes | yes |
updateCitation from a pip virtual environment |
yes | yes |
pipx run updateCitation |
yes | yes |
uvx updateCitation |
yes | yes |
Manual Use
From the top level of your repository:
pipx run updateCitation
If updateCitation is already installed in your current Python environment:
updateCitation
For Python code, the same workflow is available as:
import updateCitation
updateCitation.here()
pyproject.toml Configuration
No updateCitation configuration is required when you are happy with the defaults.
updateCitation reads standard project metadata from [project] in pyproject.toml. The most important fields are:
[project]
name = "your-package-name"
version = "0.1.0"
authors = [{ name = "Ada Lovelace", email = "ada@invented.programming" }]
keywords = ["research-software", "citation"]
license = "MIT"
urls = { Homepage = "https://example.org", Repository = "https://github.com/example/project" }
To change updateCitation behavior, add [tool.updateCitation] to pyproject.toml.
[tool.updateCitation]
filenameCitationDOTcff = "CITATION.cff"
pathFilenameCitationSSOT = "CITATION.cff"
addGitHubRelease = true
addPyPIrelease = true
projectURLTargets = ["homepage", "license", "repository"]
gitCommitMessage = "Update citations [skip ci]"
gitUserName = "updateCitation"
gitAmendFromGitHubAction = true
These are the existing [tool.updateCitation] options:
| Setting | Type | Default | Purpose |
|---|---|---|---|
filenameCitationDOTcff |
string | "CITATION.cff" |
Filename for the repository-root citation file. |
pathFilenameCitationSSOT |
string | same path as the repository-root CITATION.cff |
Authoritative source citation file. Use this if your editable citation file lives somewhere like citations/CITATION.cff. |
addGitHubRelease |
boolean | true |
Add GitHub release metadata when available. |
addPyPIrelease |
boolean | true |
Add a PyPI artifact URL when available. Set this to false for packages not published on PyPI. |
projectURLTargets |
array of strings | ["homepage", "license", "repository"] |
Choose which keys from [project.urls] are copied into CITATION.cff. Supported values are homepage, license, and repository. |
gitCommitMessage |
string | "Update citations [skip ci]" |
Commit message used when updateCitation commits from GitHub Actions. |
gitUserName |
string | "updateCitation" |
Git username used for commits from GitHub Actions. |
gitUserEmail |
string | empty string | Git email used for commits. If omitted, updateCitation tries GitHub-derived noreply addresses first and then falls back to action@github.com. |
gitAmendFromGitHubAction |
boolean | true |
If true, updateCitation commits and pushes the updated citation file when running in GitHub Actions. |
pathFilenameCitationDOTcffRepository |
string | repository root CITATION.cff path |
Advanced full-path override for the repository-root citation file. |
pathRepository |
string | current working directory | Advanced override for the repository root. Usually you should run updateCitation from the repository root instead. |
filename_pyprojectDOTtoml |
string | "pyproject.toml" |
Advanced override for the settings filename after settings are loaded. |
pathReferences |
string | citations/ under the repository root |
Accepted by the settings object, but not currently used by the main workflow. |
GITHUB_TOKEN |
string or null |
null |
GitHub API token. Prefer the GITHUB_TOKEN environment variable instead of putting secrets in pyproject.toml. |
Do not set these internal fields in [tool.updateCitation]:
pathFilenamePackageSSOTtomlPackageData
Configuration Notes
addPyPIrelease = falseprevents updateCitation from generating a newrepository-artifactURL, but it does not delete an existingrepository-artifactalready present in your source citation file.projectURLTargetsonly mapshomepage,license, andrepository.- If you override a path-related setting such as
filenameCitationDOTcfforpathRepository, also override any dependent full-path setting you rely on.
For example, a repository that keeps its editable citation file under citations/ and is not published on PyPI can use:
[tool.updateCitation]
pathFilenameCitationSSOT = "citations/CITATION.cff"
addPyPIrelease = false
Contributing
Contributions are welcome. Please feel free to submit pull requests.
Design Goals
- 100% Python.
- Dynamic self-configuration whenever possible.
- 100% of the
updateCitationsettings inpyproject.toml. - All settings for external services, such as GitHub and PyPI, use the configuration from those services instead of creating new configuration for
updateCitation. - Highly extensible for current and future services.
My Recovery
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file updatecitation-0.2.0.tar.gz.
File metadata
- Download URL: updatecitation-0.2.0.tar.gz
- Upload date:
- Size: 39.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
11e429ed91602a696b2095c260982f2e440bd7d6599b6ad397a5465db8a9724d
|
|
| MD5 |
e0a95cb4f63fe1ce38f594e69356bd84
|
|
| BLAKE2b-256 |
cb1948d3fb063ffe926f89d5eaee58bef636ded37902e1d75b2e42a1c06a7215
|