Skip to content
Open
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
111 changes: 111 additions & 0 deletions .github/workflows/release-tag-spark.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
name: Release Tag — Spark Branch Tags

# Triggers when a release rebase PR is merged into spark4.0 or spark4.1.
# Creates the spark and python derivative tags automatically.
#
# Part of the SynapseML Fabric Release Guide (Steps 1.4–1.5).
# See also: release-tag.yml (triggers the rebase PR).

on:
pull_request:
types: [closed]
branches:
- spark4.0
- spark4.1

permissions:
contents: write

jobs:
create-spark-tags:
name: Create spark & python tags
runs-on: ubuntu-latest

if: >-
github.event.pull_request.merged == true &&
startsWith(github.event.pull_request.head.ref, 'release/')

steps:
- name: Extract version and target
id: info
run: |
BRANCH="${{ github.event.pull_request.head.ref }}"
TARGET="${{ github.event.pull_request.base.ref }}"

# Extract version from branch name: release/v1.1.2-spark4.0 → 1.1.2
VERSION=$(echo "$BRANCH" | sed -E 's|release/v([0-9]+\.[0-9]+\.[0-9]+)-.*|\1|')
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "target=$TARGET" >> "$GITHUB_OUTPUT"

if ! echo "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "❌ Could not extract version from branch '$BRANCH'"
exit 1
fi

# Map branch to python version
case "$TARGET" in
spark4.0) echo "python_ver=3.12" >> "$GITHUB_OUTPUT" ;;
spark4.1) echo "python_ver=3.13" >> "$GITHUB_OUTPUT" ;;
*) echo "❌ Unknown target: $TARGET"; exit 1 ;;
esac

echo "📦 Version: $VERSION, Target: $TARGET"

- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.base.ref }}
token: ${{ secrets.GITHUB_TOKEN }}
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This checkout uses the default shallow fetch (depth 1) and may not fetch tags. That makes the later git rev-parse \"$TAG\" existence checks unreliable (it may think tags don’t exist locally), and increases the chance of push conflicts. Set fetch-depth: 0 (and ensure tags are fetched) so tag existence checks reflect the remote state.

Suggested change
token: ${{ secrets.GITHUB_TOKEN }}
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0
fetch-tags: true

Copilot uses AI. Check for mistakes.

- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

- name: Create and push tags
run: |
VERSION="${{ steps.info.outputs.version }}"
TARGET="${{ steps.info.outputs.target }}"
PYTHON_VER="${{ steps.info.outputs.python_ver }}"

SPARK_TAG="v${VERSION}-${TARGET}"
PYTHON_TAG="v${VERSION}-python${PYTHON_VER}"

for TAG in "$SPARK_TAG" "$PYTHON_TAG"; do
if git rev-parse "$TAG" >/dev/null 2>&1; then
echo "⚠️ $TAG already exists — skipping"
else
git tag "$TAG"
echo "🏷️ Created $TAG"
fi
done

git push origin "$SPARK_TAG" "$PYTHON_TAG" 2>/dev/null || true
echo "✅ Tags pushed"
Comment on lines +75 to +84
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This suppresses all push failures (auth, protected refs, network) and still prints success, which can produce false positives and hidden release errors. Since you already check for existing tags, the push should fail the job on unexpected errors; only selectively ignore the specific 'already exists' case (or push each tag with explicit error handling and clear output).

Suggested change
if git rev-parse "$TAG" >/dev/null 2>&1; then
echo "⚠️ $TAG already exists — skipping"
else
git tag "$TAG"
echo "🏷️ Created $TAG"
fi
done
git push origin "$SPARK_TAG" "$PYTHON_TAG" 2>/dev/null || true
echo "✅ Tags pushed"
if git ls-remote --exit-code --tags origin "refs/tags/$TAG" >/dev/null 2>&1; then
echo "⚠️ $TAG already exists on origin — skipping"
continue
fi
if git rev-parse "$TAG" >/dev/null 2>&1; then
echo "🏷️ $TAG already exists locally"
else
git tag "$TAG"
echo "🏷️ Created $TAG"
fi
git push origin "refs/tags/$TAG"
echo "✅ Pushed $TAG"
done
echo "✅ Tag processing complete"

Copilot uses AI. Check for mistakes.

- name: Cleanup release branch
run: |
git push origin --delete "${{ github.event.pull_request.head.ref }}" || true
echo "🧹 Cleaned up release branch"

- name: Summary
run: |
VERSION="${{ steps.info.outputs.version }}"
TARGET="${{ steps.info.outputs.target }}"
PYTHON_VER="${{ steps.info.outputs.python_ver }}"
echo ""
echo "═══════════════════════════════════════════════════"
echo " Spark Branch Tags — Summary"
echo "═══════════════════════════════════════════════════"
echo ""
echo " ✅ v${VERSION}-${TARGET} tag created"
echo " ✅ v${VERSION}-python${PYTHON_VER} tag created"
echo " 🧹 Release branch cleaned up"
echo ""
echo " Next steps:"
echo " 1. Queue ADO pipeline 17563 for refs/tags/v${VERSION}-${TARGET}"
echo " 2. Approve ESRP signing on SAW machine"
echo " 3. Proceed to Step 2 (SynapseML-Internal)"
echo ""
echo " Pipeline: https://msdata.visualstudio.com/A365/_build?definitionId=17563"
echo "═══════════════════════════════════════════════════"
125 changes: 125 additions & 0 deletions .github/workflows/release-tag.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
name: Release Tag Orchestrator

# Triggers when a primary version tag (v1.1.2) is pushed to master.
# Creates the python3.11 tag and opens a PR to rebase spark4.0.
#
# Part of the SynapseML Fabric Release Guide (Steps 1.4–1.5).
# See also: release-tag-spark.yml (creates spark/python tags after PR merge).

on:
push:
tags:
- "v[0-9]+.[0-9]+.[0-9]+"
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GitHub Actions on.push.tags uses glob patterns, not regex. The pattern v[0-9]+.[0-9]+.[0-9]+ will not match v1.2.3 as intended. Use a glob such as v*.*.* or v[0-9]*.[0-9]*.[0-9]* (and keep the strict X.Y.Z validation in the script).

Suggested change
- "v[0-9]+.[0-9]+.[0-9]+"
- "v[0-9]*.[0-9]*.[0-9]*"

Copilot uses AI. Check for mistakes.

permissions:
contents: write
pull-requests: write

jobs:
release-tags:
name: Create release tags & rebase PR
runs-on: ubuntu-latest

# Skip derivative tags (v1.1.2-spark4.0, v1.1.2-python3.11, etc.)
if: >-
!contains(github.ref_name, '-spark') &&
!contains(github.ref_name, '-python')

steps:
- name: Extract version
id: version
run: |
VERSION="${GITHUB_REF_NAME#v}"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
if ! echo "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "❌ Version '$VERSION' is not X.Y.Z format"
exit 1
fi
echo "📦 Version: $VERSION"

- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}

- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

# ── Python tag on master ───────────────────────────────
- name: Create Python 3.11 tag on master
run: |
TAG="v${{ steps.version.outputs.version }}-python3.11"
if git rev-parse "$TAG" >/dev/null 2>&1; then
echo "⚠️ $TAG already exists — skipping"
else
git tag "$TAG"
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This step claims to create the tag "on master", but it never checks out master (the workflow is triggered from a tag ref, so HEAD will be detached at the pushed tag’s commit). As written, git tag \"$TAG\" will tag the current HEAD, which might not be master. Fix by explicitly targeting origin/master (e.g., checkout/switch to master or create the tag at the origin/master commit SHA).

Suggested change
git tag "$TAG"
git tag "$TAG" origin/master

Copilot uses AI. Check for mistakes.
git push origin "$TAG"
echo "✅ Created $TAG"
fi

# ── Rebase PR for spark4.0 ─────────────────────────────
- name: Create spark4.0 rebase PR
run: |
VERSION="${{ steps.version.outputs.version }}"
BRANCH="release/v${VERSION}-spark4.0"

if ! git checkout spark4.0 2>/dev/null; then
echo "⚠️ spark4.0 branch doesn't exist — skipping"
exit 0
fi

Comment on lines +69 to +73
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

git checkout spark4.0 can fail even when the remote branch exists, because a local spark4.0 branch may not exist in the runner clone. Prefer checking out explicitly from the remote (e.g., fetch and create/reset a local branch from origin/spark4.0). This makes the workflow reliable across clean runners.

Suggested change
if ! git checkout spark4.0 2>/dev/null; then
echo "⚠️ spark4.0 branch doesn't exist — skipping"
exit 0
fi
git fetch origin spark4.0
if ! git show-ref --verify --quiet refs/remotes/origin/spark4.0; then
echo "⚠️ spark4.0 branch doesn't exist — skipping"
exit 0
fi
git checkout -B spark4.0 origin/spark4.0

Copilot uses AI. Check for mistakes.
git checkout -b "$BRANCH"
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workflow is described as idempotent, but reruns can fail or create duplicates: git checkout -b fails if the branch already exists, and gh pr create can error or open a second PR for the same head/base. Consider making this section rerun-safe by reusing/updating an existing branch (or skipping if it exists) and querying for an existing open PR for the same head/base before creating a new one.

Copilot uses AI. Check for mistakes.

if ! git rebase origin/master; then
git rebase --abort
echo "❌ Rebase conflict — manual resolution needed"
exit 1
fi

git push -u origin "$BRANCH"

gh pr create \
--base spark4.0 \
--head "$BRANCH" \
--title "chore: Rebase spark4.0 for v${VERSION} release" \
Comment on lines +82 to +87
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workflow is described as idempotent, but reruns can fail or create duplicates: git checkout -b fails if the branch already exists, and gh pr create can error or open a second PR for the same head/base. Consider making this section rerun-safe by reusing/updating an existing branch (or skipping if it exists) and querying for an existing open PR for the same head/base before creating a new one.

Copilot uses AI. Check for mistakes.
--body "## Release v${VERSION} — spark4.0 rebase

Auto-generated by the Release Tag Orchestrator.

### What this does
Rebases \`spark4.0\` onto \`master\` (tagged \`v${VERSION}\`).

### After merging
Tags \`v${VERSION}-spark4.0\` and \`v${VERSION}-python3.12\` will
be created automatically by the \`release-tag-spark\` workflow.

### Next steps
1. ✅ Merge this PR (use **Rebase and merge**)
2. Tags are auto-created on merge
3. Queue ADO pipeline 17563 for \`refs/tags/v${VERSION}\`
4. Queue ADO pipeline 17563 for \`refs/tags/v${VERSION}-spark4.0\`
5. Approve ESRP signing on SAW machine"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

# ── Summary ────────────────────────────────────────────
- name: Summary
if: always()
run: |
VERSION="${{ steps.version.outputs.version }}"
echo ""
echo "═══════════════════════════════════════════════════"
echo " Release Tag Orchestrator — Summary"
echo "═══════════════════════════════════════════════════"
echo ""
echo " Version: v${VERSION}"
echo ""
echo " ✅ v${VERSION}-python3.11 tag created on master"
echo " 📋 PR opened to rebase spark4.0"
echo " 🚧 spark4.1 skipped (WIP)"
echo ""
echo " Next: review and merge the spark4.0 rebase PR"
echo "═══════════════════════════════════════════════════"
Loading