Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 17 additions & 3 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ on:
release:
types: [published]

concurrency:
group: package-publish
cancel-in-progress: false

jobs:
publish:
if: startsWith(github.event.release.tag_name, 'data-designer-') && contains(github.event.release.tag_name, '/v')
Expand Down Expand Up @@ -120,16 +124,26 @@ jobs:
- name: Update package-list metadata asset
env:
GH_TOKEN: ${{ github.token }}
GITHUB_REPOSITORY: ${{ github.repository }}
run: |
ASSET_TAG="ddp-package-assets"
mkdir -p release-metadata
gh release download "${ASSET_TAG}" --pattern packages.json --dir release-metadata \
|| : > release-metadata/packages.json
ASSET_ID=$(gh api "repos/${GITHUB_REPOSITORY}/releases/tags/${ASSET_TAG}" \
--jq '.assets[] | select(.name == "packages.json") | .id')
if [ -n "${ASSET_ID}" ]; then
gh api \
-H "Accept: application/octet-stream" \
"repos/${GITHUB_REPOSITORY}/releases/assets/${ASSET_ID}" > release-metadata/packages.json
else
: > release-metadata/packages.json
fi
uv run ddp package-index merge \
--package-list release-metadata/packages.json \
--dist-dir dist \
--output release-metadata/packages.json
gh release delete-asset "${ASSET_TAG}" packages.json -y || true
if [ -n "${ASSET_ID}" ]; then
gh release delete-asset "${ASSET_TAG}" packages.json -y
fi
gh release upload "${ASSET_TAG}" release-metadata/packages.json
- name: Trigger Pages deployment
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ make release PLUGIN=data-designer-my-plugin PUBLISH=1
Release facts:

- Tags are per-plugin: `data-designer-my-plugin/v0.1.0`.
- Release CI expects the tagged commit to be reachable from `main`; `make release` requires a clean worktree and checks the commit against `origin/main`.
- Release CI expects the tagged commit to be reachable from `main`; `make release` requires a clean worktree and requires `HEAD` to match `origin/main`.
- Release validation requires the plugin `CODEOWNERS` file to include at least one GitHub `@user` or `@org/team` owner.
- Pre-release versions (e.g. `0.2.0a1`) are not supported by `ddp bump`; edit `pyproject.toml` manually for those.

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ build-plugin: validate-release
check-release-state:
@test -z "$$(git status --porcelain)" || { echo "ERROR: release worktree must be clean"; git status --short; exit 1; }
@git fetch origin main
@git merge-base --is-ancestor HEAD origin/main || { echo "ERROR: release commit must be reachable from origin/main"; exit 1; }
@[ "$$(git rev-parse HEAD)" = "$$(git rev-parse origin/main)" ] || { echo "ERROR: release must run from the current origin/main tip"; exit 1; }

release: check-release-state test-plugin build-plugin
@PLUGIN_VERSION=$$(uv run python -c "import tomllib; print(tomllib.load(open('$(PLUGIN_DIR)/pyproject.toml','rb'))['project']['version'])"); \
Expand Down
9 changes: 7 additions & 2 deletions docs/releasing.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ tag `data-designer-my-plugin/v0.2.0`. The tag format comes from

The release target:

- verifies that the worktree is clean and the release commit is reachable from
`origin/main`;
- verifies that the worktree is clean and `HEAD` matches the current
`origin/main` tip;
- runs that plugin's isolated tests;
- validates release metadata;
- builds the wheel and source distribution;
Expand Down Expand Up @@ -174,3 +174,8 @@ Documentation workflow is the only workflow that deploys GitHub Pages: it
downloads `ddp-package-assets/packages.json`, rebuilds the `dumb-pypi` Simple
API index, and deploys the complete Pages site with docs, catalog JSON, and the
package index in one pass.

Package publication is serialized with a workflow concurrency group because each
release updates the shared `ddp-package-assets/packages.json` asset. If multiple
plugin releases are published close together, GitHub queues the publish jobs
instead of letting them overwrite each other's package-list updates.
Loading