@@ -2,6 +2,9 @@ name: Release
22
33env :
44 OPENSTATSPEC_SPECIFICATION_DIR : ${{ github.workspace }}/openstatspec-specification
5+ OPENSTATSPEC_SPECIFICATION_PACKAGE_DIR : ${{ github.workspace }}/openstatspec-specification-package
6+ OPENSTATSPEC_SPECIFICATION_PACKAGE_REF : 2778b784afcb63868ce3c3235a5f1fa190100f9d
7+ OPENSTATSPEC_SPECIFICATION_PACKAGE_VERSION : 0.1.0
58
69on :
710 push :
@@ -21,11 +24,11 @@ jobs:
2124 build :
2225 runs-on : ubuntu-latest
2326 steps :
24- - uses : actions/checkout@v7
27+ - uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
2528 with :
2629 ref : refs/tags/${{ inputs.release_ref || github.ref_name }}
2730 fetch-depth : 0
28- - uses : actions/setup-python@v7
31+ - uses : actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
2932 with :
3033 python-version : " 3.13"
3134 - name : Verify release tag exists and targets this package version
@@ -35,22 +38,110 @@ jobs:
3538 set -eu
3639 git fetch --force --no-tags origin "refs/tags/${RELEASE_TAG}:refs/tags/${RELEASE_TAG}"
3740 python .github/verify_release_ref.py
38- - run : python -m pip install --upgrade pip build
41+ - run : python -m pip install --upgrade pip build twine pytest
3942 - name : Verify required SPSS engine is publicly installable
4043 run : >-
4144 python -m pip download --only-binary=:all: --no-deps
4245 --dest /tmp/openstatspec-engine-release
4346 openstatspec-pyspssio==0.5.1.post2
44- - name : Build clean release distributions
45- run : python -m build
4647 - name : Checkout normative specification fixtures
47- uses : actions/checkout@v7
48+ uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
4849 with :
4950 repository : OpenStatSpec/specification
5051 ref : f2fdf687d8cb32b944ca55a3e9e7215ffc603019
5152 path : openstatspec-specification
53+ - name : Checkout specification package source
54+ uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
55+ with :
56+ repository : OpenStatSpec/specification
57+ ref : ${{ env.OPENSTATSPEC_SPECIFICATION_PACKAGE_REF }}
58+ path : openstatspec-specification-package
59+ - name : Verify specification package source
60+ env :
61+ SPECIFICATION_PACKAGE_DIR : ${{ env.OPENSTATSPEC_SPECIFICATION_PACKAGE_DIR }}
62+ SPECIFICATION_PACKAGE_REF : ${{ env.OPENSTATSPEC_SPECIFICATION_PACKAGE_REF }}
63+ SPECIFICATION_PACKAGE_VERSION : ${{ env.OPENSTATSPEC_SPECIFICATION_PACKAGE_VERSION }}
64+ run : |
65+ python - <<'PY'
66+ import os
67+ import subprocess
68+ import tomllib
69+ from pathlib import Path
70+
71+ source = Path(os.environ["SPECIFICATION_PACKAGE_DIR"])
72+ expected_ref = os.environ["SPECIFICATION_PACKAGE_REF"]
73+ actual_ref = subprocess.check_output(
74+ ["git", "rev-parse", "HEAD"], cwd=source, text=True,
75+ ).strip()
76+ if actual_ref != expected_ref:
77+ raise SystemExit(
78+ f"specification package ref {actual_ref!r} does not match "
79+ f"expected {expected_ref!r}"
80+ )
81+ project = tomllib.loads(
82+ (source / "pyproject.toml").read_text(encoding="utf-8")
83+ )["project"]
84+ if project["name"] != "openstatspec-specification":
85+ raise SystemExit("unexpected specification package name")
86+ expected_version = os.environ["SPECIFICATION_PACKAGE_VERSION"]
87+ if project["version"] != expected_version:
88+ raise SystemExit(
89+ f"specification package version {project['version']!r} does "
90+ f"not match expected {expected_version!r}"
91+ )
92+ for required in (
93+ "pyproject.toml",
94+ "src/openstatspec_specification/dolt.py",
95+ "sql/dolt-adapter-declaration-schema.json",
96+ ):
97+ if not (source / required).is_file():
98+ raise SystemExit(f"missing specification package resource: {required}")
99+ PY
100+ - name : Verify specification package tests and repository
101+ run : |
102+ python -m pip install -e "$OPENSTATSPEC_SPECIFICATION_PACKAGE_DIR"
103+ python -m pytest -q "$OPENSTATSPEC_SPECIFICATION_PACKAGE_DIR/tests/test_dolt_declarations.py"
104+ python "$OPENSTATSPEC_SPECIFICATION_PACKAGE_DIR/tools/validate_repository.py"
105+ - name : Build clean release distributions
106+ run : |
107+ rm -rf dist /tmp/openstatspec-release-dists
108+ mkdir -p dist /tmp/openstatspec-release-dists/openstatspec /tmp/openstatspec-release-dists/specification
109+ python -m build --outdir /tmp/openstatspec-release-dists/openstatspec .
110+ python -m build --outdir /tmp/openstatspec-release-dists/specification "$OPENSTATSPEC_SPECIFICATION_PACKAGE_DIR"
111+ python -m twine check \
112+ /tmp/openstatspec-release-dists/openstatspec/* \
113+ /tmp/openstatspec-release-dists/specification/*
114+ python - <<'PY'
115+ from pathlib import Path
116+ from shutil import copy2
117+
118+ sources = {
119+ "openstatspec": Path("/tmp/openstatspec-release-dists/openstatspec"),
120+ "openstatspec_specification": Path("/tmp/openstatspec-release-dists/specification"),
121+ }
122+ copied = []
123+ for normalized_name, source in sources.items():
124+ files = sorted(path for path in source.iterdir() if path.is_file())
125+ if len(files) != 2 or {path.suffix for path in files} != {".whl", ".gz"}:
126+ raise SystemExit(
127+ f"expected one wheel and one sdist for {normalized_name}, got "
128+ f"{[path.name for path in files]}"
129+ )
130+ for path in files:
131+ normalized_artifact = path.name.replace("-", "_").lower()
132+ if not normalized_artifact.startswith(normalized_name + "_"):
133+ raise SystemExit(
134+ f"unexpected artifact name for {normalized_name}: {path.name}"
135+ )
136+ destination = Path("dist") / path.name
137+ copy2(path, destination)
138+ copied.append(destination)
139+ if len(copied) != 4:
140+ raise SystemExit(f"expected four release artifacts, got {len(copied)}")
141+ print("release artifacts:", ", ".join(path.name for path in copied))
142+ PY
52143 - name : Checkout required SPSS engine
53- uses : actions/checkout@v7
144+ uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
54145 with :
55146 repository : TonisOrmisson/pyspssio
56147 ref : e069adf33c70bcd9e8e6ee495106479463a84fa2
@@ -60,9 +151,21 @@ jobs:
60151 - run : python -m pytest -m "not services"
61152 - run : python -m venv /tmp/openstatspec-release-smoke
62153 - run : /tmp/openstatspec-release-smoke/bin/python -m pip install ./openstatspec-pyspssio
63- - run : /tmp/openstatspec-release-smoke/bin/python -m pip install dist/*.whl
154+ - run : /tmp/openstatspec-release-smoke/bin/python -m pip install dist/openstatspec- *.whl
64155 - run : /tmp/openstatspec-release-smoke/bin/openstatspec capabilities
65- - uses : actions/upload-artifact@v7
156+ - name : Smoke-test specification wheel
157+ run : |
158+ python -m venv /tmp/openstatspec-specification-release-smoke
159+ /tmp/openstatspec-specification-release-smoke/bin/python -m pip install dist/openstatspec_specification-*.whl
160+ /tmp/openstatspec-specification-release-smoke/bin/python - <<'PY'
161+ from openstatspec_specification import DoltDeclarationSource
162+
163+ source = DoltDeclarationSource.packaged()
164+ schema = source.read_json("sql/dolt-adapter-declaration-schema.json")
165+ if schema.get("schema_id") != "openstatspec-dolt-adapter-declaration-v1":
166+ raise SystemExit("packaged specification schema has the wrong identifier")
167+ PY
168+ - uses : actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
66169 with :
67170 name : python-distributions
68171 path : dist/
@@ -76,10 +179,10 @@ jobs:
76179 permissions :
77180 id-token : write
78181 steps :
79- - uses : actions/download-artifact@v8
182+ - uses : actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
80183 with :
81184 name : python-distributions
82185 path : dist/
83- - uses : pypa/gh-action-pypi-publish@release/v1
186+ - uses : pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
84187 with :
85188 skip-existing : true
0 commit comments