Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
10 changes: 6 additions & 4 deletions .github/workflows/pre-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ name: Pre-Release
# Build the same core wheel matrix as the stable release workflows and attach
# the artifacts to a GitHub Pre-release. Also publish the exact artifacts to
# TestPyPI, then consume them in smoke and T-one tests. No production PyPI upload.
# Stable vX.Y.Z / vX.Y.Z.postN tags go to release*.yaml instead. Tags that match
# neither set (e.g. v0.3.14a1, v0.3.14post1) trigger no workflow at all.
on:
push:
tags:
- 'v*-rc*'
- 'v*-alpha*'
- 'v*-beta*'
- 'v*-pre*'
- 'v*rc*'
- 'v*alpha*'
- 'v*beta*'
- 'v*pre*'

jobs:
version-stamp:
Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/release-cuda13.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ name: Release CUDA 13

on:
push:
# Stable tags only (vX.Y.Z or vX.Y.Z.postN). PEP 440 pre-release tags
# such as v0.3.14rc1 must not reach production PyPI; pre-release.yaml
# handles them.
tags:
- 'v*'
- 'v[0-9]+.[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+.post[0-9]+'

jobs:
build:
Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/release-efa-cuda13.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ name: Release EFA CUDA 13

on:
push:
# Stable tags only (vX.Y.Z or vX.Y.Z.postN). PEP 440 pre-release tags
# such as v0.3.14rc1 must not reach production PyPI; pre-release.yaml
# handles them.
tags:
- 'v*'
- 'v[0-9]+.[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+.post[0-9]+'

# Publishes mooncake-transfer-engine-efa-cuda13, the CUDA 13-aware AWS EFA wheel.
jobs:
Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/release-efa-non-cuda.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ name: Release EFA Non-CUDA

on:
push:
# Stable tags only (vX.Y.Z or vX.Y.Z.postN). PEP 440 pre-release tags
# such as v0.3.14rc1 must not reach production PyPI; pre-release.yaml
# handles them.
tags:
- 'v*'
- 'v[0-9]+.[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+.post[0-9]+'

# Publishes mooncake-transfer-engine-efa-non-cuda, the CPU/DRAM AWS EFA wheel.
jobs:
Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/release-efa.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ name: Release EFA

on:
push:
# Stable tags only (vX.Y.Z or vX.Y.Z.postN). PEP 440 pre-release tags
# such as v0.3.14rc1 must not reach production PyPI; pre-release.yaml
# handles them.
tags:
- 'v*'
- 'v[0-9]+.[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+.post[0-9]+'

# Publishes mooncake-transfer-engine-efa, the CUDA 12-aware AWS EFA wheel.
jobs:
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/release-musa.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ name: Release MUSA

on:
push:
# Stable tags only (vX.Y.Z or vX.Y.Z.postN). PEP 440 pre-release tags
# such as v0.3.14rc1 must not reach production PyPI; pre-release.yaml
# handles them.
tags:
- 'v*'
- 'v[0-9]+.[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+.post[0-9]+'
workflow_dispatch:
inputs:
tag:
Expand Down Expand Up @@ -50,7 +54,7 @@ jobs:
RELEASE_TAG: ${{ inputs.tag }}
run: |
set -euo pipefail
if [[ "${RELEASE_TAG}" != v* || "${RELEASE_TAG}" == *-* ]]; then
if [[ ! "${RELEASE_TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(\.post[0-9]+)?$ ]]; then
echo "::error::Backfill tag must be a stable release tag starting with v"
exit 1
fi
Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/release-non-cuda.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ name: Release Non-CUDA

on:
push:
# Stable tags only (vX.Y.Z or vX.Y.Z.postN). PEP 440 pre-release tags
# such as v0.3.14rc1 must not reach production PyPI; pre-release.yaml
# handles them.
tags:
- 'v*'
- 'v[0-9]+.[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+.post[0-9]+'

jobs:
# manylinux2_28 for the toolchain only (USE_CUDA=OFF); keeps the glibc floor
Expand Down
17 changes: 16 additions & 1 deletion .github/workflows/release-npu.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ name: Release Ascend NPU

on:
push:
# Stable tags only (vX.Y.Z or vX.Y.Z.postN). PEP 440 pre-release tags
# such as v0.3.14rc1 must not reach production PyPI; pre-release.yaml
# handles them.
tags:
- 'v*'
- 'v[0-9]+.[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+.post[0-9]+'
workflow_dispatch:
inputs:
tag:
Expand Down Expand Up @@ -43,6 +47,17 @@ jobs:
ref: ${{ github.event_name == 'workflow_dispatch' && format('refs/tags/{0}', inputs.tag) || github.ref }}
fetch-depth: 0

- name: Validate release tag
shell: bash
env:
RELEASE_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }}
run: |
set -euo pipefail
if [[ ! "${RELEASE_TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(\.post[0-9]+)?$ ]]; then
echo "::error::Release tag must be a stable release tag (vX.Y.Z or vX.Y.Z.postN)"
exit 1
fi

- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/release-rocm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ name: Release ROCm

on:
push:
# Stable tags only (vX.Y.Z or vX.Y.Z.postN). PEP 440 pre-release tags
# such as v0.3.14rc1 must not reach production PyPI; pre-release.yaml
# handles them.
tags:
- 'v*'
- 'v[0-9]+.[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+.post[0-9]+'
workflow_dispatch:
inputs:
tag:
Expand Down Expand Up @@ -79,7 +83,7 @@ jobs:
RELEASE_TAG: ${{ inputs.tag }}
run: |
set -euo pipefail
if [[ "${RELEASE_TAG}" != v* || "${RELEASE_TAG}" == *-* ]]; then
if [[ ! "${RELEASE_TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(\.post[0-9]+)?$ ]]; then
echo "::error::Backfill tag must be a stable release tag starting with v"
exit 1
fi
Expand Down
8 changes: 7 additions & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@ name: Release

on:
push:
# Stable tags only (vX.Y.Z or vX.Y.Z.postN). PEP 440 pre-release tags
# such as v0.3.14rc1 must not reach production PyPI; pre-release.yaml
# handles them. Any other form (v0.3.14a1, v0.3.14dev1, v0.3.14post1,
# v0.3.14+local) matches no release workflow, so nothing runs: re-tag
# in one of the forms above instead of pushing the same tag again.
tags:
- 'v*'
- 'v[0-9]+.[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+.post[0-9]+'

jobs:
# Skip semver pre-release tags (e.g. v1.0.0-rc1); those are handled by pre-release.yaml.
Expand Down
100 changes: 100 additions & 0 deletions scripts/ci/tests/test_release_tag_filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
from pathlib import Path
import re
import unittest

import yaml


REPOSITORY = Path(__file__).resolve().parents[3]
WORKFLOWS = REPOSITORY / ".github" / "workflows"

STABLE_RELEASE_WORKFLOWS = (
"release.yaml",
"release-cuda13.yaml",
"release-efa.yaml",
"release-efa-cuda13.yaml",
"release-efa-non-cuda.yaml",
"release-musa.yaml",
"release-non-cuda.yaml",
"release-npu.yaml",
"release-rocm.yaml",
)

STABLE_TAGS = ("v0.3.14", "v1.0.0", "v0.3.12.post1", "v0.3.10.post12")
PRERELEASE_TAGS = (
"v0.3.14rc1",
"v0.3.14-rc1",
"v0.3.14.rc1",
"v0.3.14alpha1",
"v0.3.14-alpha.1",
"v0.3.14beta2",
"v0.3.14-pre1",
)
NON_RELEASE_TAGS = PRERELEASE_TAGS + (
"v0.3.14a1",
"v0.3.14b1",
"v0.3.14.dev1",
"v0.3.14+local",
"v0.3",
"vnext",
)


def github_filter_to_regex(pattern):
"""Translate a GitHub Actions branch/tag filter pattern to a regex."""
regex = []
index = 0
while index < len(pattern):
char = pattern[index]
if pattern.startswith("**", index):
regex.append(".*")
index += 2
continue
if char == "*":
regex.append("[^/]*")
elif char in "+?":
regex.append(char)
elif char == "[":
end = pattern.index("]", index)
regex.append(pattern[index : end + 1])
index = end
else:
regex.append(re.escape(char))
index += 1
return re.compile("".join(regex))


def tag_patterns(name):
with (WORKFLOWS / name).open() as workflow_file:
workflow = yaml.safe_load(workflow_file)
triggers = workflow.get("on", workflow.get(True))
return triggers["push"]["tags"]


def matches(patterns, tag):
return any(github_filter_to_regex(p).fullmatch(tag) for p in patterns)


class ReleaseTagFilterTest(unittest.TestCase):
def test_stable_release_workflows_only_trigger_on_stable_tags(self):
for name in STABLE_RELEASE_WORKFLOWS:
patterns = tag_patterns(name)
for tag in STABLE_TAGS:
with self.subTest(workflow=name, tag=tag):
self.assertTrue(matches(patterns, tag))
for tag in NON_RELEASE_TAGS:
with self.subTest(workflow=name, tag=tag):
self.assertFalse(matches(patterns, tag))

def test_pre_release_workflow_triggers_on_prerelease_tags(self):
patterns = tag_patterns("pre-release.yaml")
for tag in PRERELEASE_TAGS:
with self.subTest(tag=tag):
self.assertTrue(matches(patterns, tag))
for tag in STABLE_TAGS:
with self.subTest(tag=tag):
self.assertFalse(matches(patterns, tag))


if __name__ == "__main__":
unittest.main()
Loading