Skip to content

Commit f8fd865

Browse files
authored
Chore: redo zenodo sync (#685)
1 parent 17b4c5c commit f8fd865

3 files changed

Lines changed: 87 additions & 30 deletions

File tree

.github/workflows/publish-pypi.yml

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
name: Publish to PyPI
2+
23
on:
34
pull_request:
45
push:
5-
tags: ["v*"]
6+
tags:
7+
- "v*"
68

79
concurrency:
8-
group: publish-pypi-{{ github.sha }}
10+
group: publish-pypi-${{ github.sha }}
911
cancel-in-progress: false
1012

1113
jobs:
@@ -17,28 +19,25 @@ jobs:
1719
with:
1820
fetch-depth: 0
1921

20-
- name: Get tags
21-
run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
22-
shell: bash
23-
2422
- uses: actions/setup-python@v6
2523
with:
2624
python-version: "3.12"
2725

28-
- name: Sync citation metadata for release tags
29-
if: github.event_name == 'push'
26+
- name: Ensure clean tree before build
3027
run: |
31-
python tools/release/sync_citation.py --tag "${GITHUB_REF_NAME}"
28+
git diff --quiet || (git status --short && git diff && exit 1)
3229
shell: bash
3330

3431
- name: Build package
3532
run: |
36-
python -m pip install --upgrade pip wheel setuptools setuptools_scm build twine
33+
python -m pip install --upgrade pip
34+
python -m pip install wheel setuptools setuptools_scm build twine
3735
python -m build --sdist --wheel . --outdir dist
36+
shell: bash
3837

3938
- name: Check files
4039
run: |
41-
ls dist
40+
ls -lah dist
4241
shell: bash
4342

4443
- name: Test wheels
@@ -84,7 +83,7 @@ jobs:
8483

8584
- name: Check files
8685
run: |
87-
ls dist
86+
ls -lah dist
8887
shell: bash
8988

9089
- name: Publish to TestPyPI
@@ -97,11 +96,11 @@ jobs:
9796
publish-pypi:
9897
name: Publish to PyPI
9998
needs: publish-pypi-test
99+
if: github.event_name == 'push'
100100
environment:
101101
name: prod
102102
url: https://pypi.org/project/ultraplot/
103103
runs-on: ubuntu-latest
104-
if: github.event_name == 'push'
105104
permissions:
106105
id-token: write
107106
contents: read
@@ -114,7 +113,7 @@ jobs:
114113

115114
- name: Check files
116115
run: |
117-
ls dist
116+
ls -lah dist
118117
shell: bash
119118

120119
- name: Publish to PyPI
@@ -150,17 +149,14 @@ jobs:
150149
with:
151150
fetch-depth: 0
152151

153-
- name: Get tags
154-
run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
155-
shell: bash
156-
157152
- uses: actions/setup-python@v6
158153
with:
159154
python-version: "3.12"
160155

161156
- name: Install release tooling
162157
run: |
163-
python -m pip install --upgrade pip PyYAML
158+
python -m pip install --upgrade pip
159+
python -m pip install PyYAML
164160
shell: bash
165161

166162
- name: Download artifacts
@@ -169,12 +165,21 @@ jobs:
169165
name: dist-${{ github.sha }}-${{ github.run_id }}-${{ github.run_number }}
170166
path: dist
171167

172-
- name: Sync citation metadata for release tags
168+
- name: Generate release citation metadata
169+
run: |
170+
python tools/release/sync_citation.py \
171+
--tag "${GITHUB_REF_NAME}" \
172+
--output "${RUNNER_TEMP}/CITATION.cff"
173+
shell: bash
174+
175+
- name: Check tree stayed clean
173176
run: |
174-
python tools/release/sync_citation.py --tag "${GITHUB_REF_NAME}"
177+
git diff --quiet || (git status --short && git diff && exit 1)
175178
shell: bash
176179

177180
- name: Publish to Zenodo
178181
run: |
179-
python tools/release/publish_zenodo.py --dist-dir dist
182+
python tools/release/publish_zenodo.py \
183+
--dist-dir dist \
184+
--citation-file "${RUNNER_TEMP}/CITATION.cff"
180185
shell: bash

tools/release/publish_zenodo.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ def parse_args() -> argparse.Namespace:
4242
default=Path("CITATION.cff"),
4343
help="Path to the repository CITATION.cff file.",
4444
)
45+
parser.add_argument(
46+
"--citation-file",
47+
type=Path,
48+
default=Path("CITATION.cff"),
49+
help="Path to the citation metadata file to upload.",
50+
)
4551
parser.add_argument(
4652
"--pyproject",
4753
type=Path,

tools/release/sync_citation.py

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,16 @@ def parse_args() -> argparse.Namespace:
2020
"--citation",
2121
type=Path,
2222
default=Path("CITATION.cff"),
23-
help="Path to the repository CITATION.cff file.",
23+
help="Path to the source CITATION.cff file.",
24+
)
25+
parser.add_argument(
26+
"--output",
27+
type=Path,
28+
default=None,
29+
help=(
30+
"Optional output path for the synced citation file. "
31+
"Defaults to overwriting --citation."
32+
),
2433
)
2534
parser.add_argument(
2635
"--date",
@@ -78,44 +87,81 @@ def replace_scalar(text: str, key: str, value: str) -> str:
7887
return updated
7988

8089

81-
def sync_citation(
90+
def build_synced_citation(
8291
citation_path: Path,
8392
*,
8493
tag: str,
8594
release_date: str | None = None,
8695
repo_root: Path | None = None,
87-
check: bool = False,
88-
) -> bool:
96+
) -> tuple[str, str, bool]:
8997
repo_root = repo_root or citation_path.resolve().parent
9098
version = tag_version(tag)
9199
release_date = release_date or resolve_release_date(tag, repo_root)
100+
92101
original = citation_path.read_text(encoding="utf-8")
93102
updated = replace_scalar(original, "version", version)
94103
updated = replace_scalar(updated, "date-released", release_date)
95104
changed = updated != original
105+
return original, updated, changed
106+
107+
108+
def sync_citation(
109+
citation_path: Path,
110+
*,
111+
tag: str,
112+
output_path: Path | None = None,
113+
release_date: str | None = None,
114+
repo_root: Path | None = None,
115+
check: bool = False,
116+
) -> bool:
117+
original, updated, changed = build_synced_citation(
118+
citation_path,
119+
tag=tag,
120+
release_date=release_date,
121+
repo_root=repo_root,
122+
)
123+
96124
if check:
97125
if changed:
98126
raise SystemExit(
99127
f"{citation_path} is out of date for {normalize_tag(tag)}. "
100128
"Run tools/release/sync_citation.py before releasing."
101129
)
102130
return False
103-
citation_path.write_text(updated, encoding="utf-8")
131+
132+
destination = output_path or citation_path
133+
destination.parent.mkdir(parents=True, exist_ok=True)
134+
destination.write_text(updated, encoding="utf-8")
104135
return changed
105136

106137

107138
def main() -> int:
108139
args = parse_args()
140+
destination = args.output or args.citation
141+
109142
changed = sync_citation(
110143
args.citation,
111144
tag=args.tag,
145+
output_path=args.output,
112146
release_date=args.date,
113147
repo_root=Path.cwd(),
114148
check=args.check,
115149
)
116-
action = "Validated" if args.check else "Updated"
117-
print(f"{action} {args.citation} for {normalize_tag(args.tag)}.")
118-
return 0 if (args.check or changed or not changed) else 0
150+
151+
if args.check:
152+
print(f"Validated {args.citation} for {normalize_tag(args.tag)}.")
153+
else:
154+
source = args.citation.resolve()
155+
dest = destination.resolve()
156+
if source == dest:
157+
print(f"Updated {args.citation} for {normalize_tag(args.tag)}.")
158+
else:
159+
print(
160+
f"Wrote synced citation metadata from {args.citation} "
161+
f"to {destination} for {normalize_tag(args.tag)}."
162+
)
163+
164+
return 0
119165

120166

121167
if __name__ == "__main__":

0 commit comments

Comments
 (0)