Skip to content

Commit 29ce692

Browse files
authored
Add Harvard Dataverse release makefile command (#188)
1 parent ec31f5e commit 29ce692

15 files changed

Lines changed: 167 additions & 218 deletions

File tree

.github/actions/setup-uv/action.yml

Lines changed: 0 additions & 27 deletions
This file was deleted.

.github/workflows/ci.yml

Lines changed: 30 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,28 @@ name: Integration checks
33
on:
44
pull_request:
55

6+
concurrency:
7+
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
8+
cancel-in-progress: true
9+
10+
permissions:
11+
contents: read
12+
613
env:
714
CLICOLOR: 1
8-
PYTHON_VERSION: 3.12
9-
RUFF_VERSION: 0.9.1 # Using same version as pre-commit-config.yaml
1015

1116
jobs:
12-
uv:
17+
type-check:
1318
runs-on: ubuntu-latest
19+
timeout-minutes: 15
1420
steps:
1521
- uses: actions/checkout@v6
1622

1723
- name: Setup uv
1824
uses: astral-sh/setup-uv@v7
19-
id: setup-uv
20-
with:
21-
enable-cache: true
22-
ignore-nothing-to-cache: true
23-
pyproject-file: "pyproject.toml"
24-
python-version: ${{ env.PYTHON_VERSION }}
25-
cache-dependency-glob: |
26-
**/pyproject.toml
27-
**/uv.lock
28-
29-
- name: Log if uv cache was restored
30-
if: steps.setup-uv.outputs.cache-hit == 'true'
31-
run: echo "Cache was restored"
32-
33-
- name: Print the installed uv version
34-
run: echo "Installed uv version is ${{ steps.setup-uv.outputs.uv-version }}"
3525

3626
- name: Install the project dependencies
37-
run: uv sync --all-groups
27+
run: uv sync --all-groups --frozen
3828

3929
- name: Run ty
4030
run: make ty
@@ -44,68 +34,39 @@ jobs:
4434

4535
formatting:
4636
runs-on: ubuntu-latest
37+
timeout-minutes: 5
4738
steps:
4839
- uses: actions/checkout@v6
4940

5041
- name: Spell Check
5142
uses: crate-ci/typos@v1.45.1
5243

53-
- name: Formatting
44+
- name: Lint
5445
uses: astral-sh/ruff-action@v3
5546
with:
56-
version: ${{ env.RUFF_VERSION }}
57-
args: check --fix --exit-non-zero-on-fix
47+
args: check
48+
49+
- name: Format check
50+
uses: astral-sh/ruff-action@v3
51+
with:
52+
args: format --check
5853

5954
semver-bump:
6055
runs-on: ubuntu-latest
61-
env:
62-
TARGET_BRANCH: ${{ github.base_ref }}
63-
HEAD_BRANCH: ${{ github.head_ref }}
56+
timeout-minutes: 5
6457
steps:
65-
- name: Checkout repository
66-
uses: actions/checkout@v6
58+
- uses: actions/checkout@v6
6759
with:
6860
fetch-depth: 0
6961

70-
- name: Set up Python
71-
uses: actions/setup-python@v6
62+
- name: Setup uv
63+
uses: astral-sh/setup-uv@v7
64+
65+
- uses: rayepps/require-semver-bump@v1
66+
env:
67+
GITHUB_TOKEN: ${{ github.token }}
7268
with:
73-
python-version: ${{ env.PYTHON_VERSION }}
74-
cache: "pip"
75-
76-
- name: Fetch branches
77-
run: |
78-
git fetch origin ${TARGET_BRANCH}
79-
git fetch origin ${HEAD_BRANCH}
80-
81-
- name: Install dependencies
82-
run: pip install packaging
83-
84-
- name: Check version bump
85-
shell: bash
86-
run: |
87-
# Extract versions from both branches
88-
old_version=$(git show origin/${TARGET_BRANCH}:pyproject.toml | grep "^version = " | cut -d'"' -f2 || echo "0.0.0")
89-
new_version=$(git show origin/${HEAD_BRANCH}:pyproject.toml | grep "^version = " | cut -d'"' -f2)
90-
91-
echo "Previous version: ${old_version}"
92-
echo "New version: ${new_version}"
93-
94-
# Compare versions using Python
95-
version_increased=$(python - <<EOF
96-
from packaging import version
97-
old = version.parse("${old_version}")
98-
new = version.parse("${new_version}")
99-
print(new > old)
100-
EOF
101-
)
102-
103-
if [ "${version_increased}" = "False" ]; then
104-
echo "::error::Version must be bumped according to semantic versioning."
105-
echo "Current version: ${old_version}"
106-
echo "Proposed version: ${new_version}"
107-
echo "Please update the version in pyproject.toml"
108-
exit 1
109-
else
110-
echo "✅ Version bump verified: ${old_version} -> ${new_version}"
111-
fi
69+
file: pyproject.toml
70+
pattern: >
71+
version = ["'](.+?)["']
72+

.github/workflows/publish-pypi.yml

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,28 @@ name: Publish PyPI client
33
on:
44
workflow_call:
55
inputs:
6-
package-name:
7-
description: PyPI package name (used for the environment URL)
8-
required: true
9-
type: string
106
package-dir:
117
description: Path to the package directory containing pyproject.toml
128
required: true
139
type: string
14-
python-version:
15-
description: Python version to install
16-
required: false
17-
type: string
18-
default: "3.12"
10+
11+
permissions:
12+
contents: read
1913

2014
jobs:
2115
publish:
22-
name: Publish ${{ inputs.package-name }} to PyPI
16+
name: Publish to PyPI
2317
runs-on: ubuntu-latest
24-
environment:
25-
name: pypi
26-
url: https://pypi.org/p/${{ inputs.package-name }}
18+
timeout-minutes: 10
19+
environment: pypi
2720
permissions:
2821
id-token: write
2922
contents: read
3023
steps:
3124
- uses: actions/checkout@v6
3225

3326
- name: Setup uv
34-
uses: ./.github/actions/setup-uv
35-
with:
36-
python-version: ${{ inputs.python-version }}
27+
uses: astral-sh/setup-uv@v7
3728

3829
- name: Check if local version is greater than PyPI
3930
id: version_check
@@ -44,6 +35,5 @@ jobs:
4435
- name: Build and publish to PyPI
4536
if: steps.version_check.outputs.local_version_is_higher == 'true'
4637
run: |
47-
uv build ${{ inputs.package-dir }}
48-
uv publish ${{ inputs.package-dir }}/dist/*
49-
38+
uv build "${{ inputs.package-dir }}"
39+
uv publish "${{ inputs.package-dir }}"/dist/*.whl "${{ inputs.package-dir }}"/dist/*.tar.gz

.github/workflows/release.yml

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,58 +2,59 @@ name: Release
22

33
on:
44
push:
5-
branches: main
5+
branches: [main]
6+
workflow_dispatch:
67

7-
env:
8-
PYTHON_VERSION: "3.12"
8+
permissions:
9+
contents: read
910

1011
jobs:
1112
release:
1213
name: Create Release
1314
runs-on: ubuntu-latest
15+
timeout-minutes: 5
16+
permissions:
17+
contents: write
18+
outputs:
19+
should-publish: ${{ steps.tag_check.outputs.exists == 'false' }}
1420
steps:
1521
- uses: actions/checkout@v6
16-
17-
- name: Setup uv
18-
uses: ./.github/actions/setup-uv
19-
with:
20-
python-version: ${{ env.PYTHON_VERSION }}
21-
cache-dependency-glob: |
22-
**/pyproject.toml
23-
**/uv.lock
24-
25-
- name: Build Kedro Viz
26-
run: uv run kedro viz build
27-
28-
- name: Upload Kedro Viz to Vercel Blob
29-
uses: dartilesm/vercel-blob-action@v2
3022
with:
31-
source: build/
32-
destination: build/ # NOTE: we could use "${{ github.sha }}/build/" but we want to re-write the folder in the blob storage.
33-
read-write-token: ${{ secrets.VERCEL_BLOB_READ_WRITE_TOKEN }}
23+
fetch-depth: 0
3424

3525
- name: Read project version
3626
id: project_version
37-
uses: SebRollen/toml-action@v1.2.0
27+
uses: maybe-hello-world/pyproject-check-version@v4
3828
with:
39-
file: pyproject.toml
40-
field: project.version
29+
pyproject-path: pyproject.toml
30+
31+
- name: Check if tag already exists
32+
id: tag_check
33+
env:
34+
TAG: ${{ steps.project_version.outputs.local_version }}
35+
run: |
36+
if git rev-parse "refs/tags/${TAG}" >/dev/null 2>&1; then
37+
echo "Tag ${TAG} already exists — skipping release."
38+
echo "exists=true" >> "$GITHUB_OUTPUT"
39+
else
40+
echo "exists=false" >> "$GITHUB_OUTPUT"
41+
fi
4142
4243
- name: Create GitHub Release
44+
if: steps.tag_check.outputs.exists == 'false'
4345
uses: softprops/action-gh-release@v3
4446
env:
4547
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4648
with:
47-
tag_name: ${{ steps.project_version.outputs.value }}
48-
name: Release ${{ steps.project_version.outputs.value }}
49+
tag_name: ${{ steps.project_version.outputs.local_version }}
50+
name: Release ${{ steps.project_version.outputs.local_version }}
4951
draft: false
5052
prerelease: false
5153

5254
publish:
5355
name: Publish client
5456
needs: release
57+
if: needs.release.outputs.should-publish == 'true'
5558
uses: ./.github/workflows/publish-pypi.yml
5659
with:
57-
package-name: optimuskg
5860
package-dir: packages/optimuskg
59-
python-version: "3.12"

.gitignore

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,6 @@ target/
131131
# Jupyter Notebook
132132
.ipynb_checkpoints
133133

134-
# pyenv
135-
.python-version
136-
137134
# celery beat schedule file
138135
celerybeat-schedule
139136

.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.12

Makefile

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,37 @@ kedro-viz: ##@ Run kedro viz
9494
@uv run kedro viz --include-hooks
9595

9696
# -----------------------------------------------
97-
##@ Documentation
97+
# Dataverse
98+
# -----------------------------------------------
99+
100+
DATAVERSE_SERVER ?= https://dataverse.harvard.edu
101+
DATAVERSE_PID ?= doi:10.7910/DVN/IYNGEV
102+
DATAVERSE_DIR ?= data/gold/kg/parquet
103+
104+
.PHONY: dataverse-release
105+
dataverse-release: ##@ Upload gold parquet files to Harvard Dataverse as a draft (override DATAVERSE_PID, DATAVERSE_SERVER, DATAVERSE_DIR; requires DATAVERSE_TOKEN)
106+
@if [ -z "$$DATAVERSE_TOKEN" ]; then \
107+
echo "DATAVERSE_TOKEN is not set. Generate one at $(DATAVERSE_SERVER)/dataverseuser.xhtml?selectTab=apiTokenTab and export it."; \
108+
exit 1; \
109+
fi
110+
@if [ ! -d "$(DATAVERSE_DIR)" ]; then \
111+
echo "Directory $(DATAVERSE_DIR) does not exist. Run the gold pipeline first."; \
112+
exit 1; \
113+
fi
114+
@echo "Uploading $(DATAVERSE_DIR) to $(DATAVERSE_PID) on $(DATAVERSE_SERVER) (draft)..."
115+
@uvx dvuploader \
116+
--pid $(DATAVERSE_PID) \
117+
--api-token $$DATAVERSE_TOKEN \
118+
--dataverse-url $(DATAVERSE_SERVER) \
119+
--recurse \
120+
$(DATAVERSE_DIR)
121+
@echo
122+
@echo "Upload complete. Review the draft at:"
123+
@echo " $(DATAVERSE_SERVER)/dataset.xhtml?persistentId=$(DATAVERSE_PID)&version=DRAFT"
124+
@echo "Then publish (major version) from the Dataverse UI."
125+
126+
# -----------------------------------------------
127+
# Documentation
98128
# -----------------------------------------------
99129

100130
.PHONY: docs-dev

cli/commands/evals/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Evaluation dataset computation for knowledge graph analysis."""
22

33
import logging
4-
from enum import Enum
4+
from enum import StrEnum
55
from pathlib import Path
66

77
import typer
@@ -185,7 +185,7 @@ def sample_edges_cmd( # noqa: PLR0913
185185
)
186186

187187

188-
class ActionType(str, Enum):
188+
class ActionType(StrEnum):
189189
submit = "submit"
190190
poll = "poll"
191191

cli/commands/schema.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
def _format_dataset_display(ds_name: str, ds_type: str) -> str:
1515
display_name = format_rich(ds_name, "dark_orange")
16-
type_name = ds_type.split(".")[-1]
16+
type_name = ds_type.rsplit(".", maxsplit=1)[-1]
1717
return f"{display_name} ({type_name})"
1818

1919

0 commit comments

Comments
 (0)