Skip to content

part 4c rel v25.9.1 #27

part 4c rel v25.9.1

part 4c rel v25.9.1 #27

Workflow file for this run

name: release
on:
# Auto-trigger after wheel builds complete
workflow_run:
workflows: ["wheels", "wheels-docker", "wstest"]
types: [completed]
# For PR summaries (runs in main repo context with write permissions)
pull_request_target:
types: [opened, synchronize, reopened]
# Manual dispatch for debugging
workflow_dispatch:
inputs:
pr_number:
description: "PR number to post summary for"
required: false
type: string
jobs:
identifiers:
# GitHub needs to know where .cicd/workflows/identifiers.yml lives at parse time,
# and submodules aren't included in that context! thus the following does NOT work:
# uses: ./.cicd/workflows/identifiers.yml
# we MUST reference the remote repo directly:
uses: wamp-proto/wamp-cicd/.github/workflows/identifiers.yml@main
# IMPORTANT: we still need .cicd as a Git submodule in the using repo though!
# because e.g. identifiers.yml wants to access scripts/sanitize.sh !
# Nightly and stable GitHub releases (consolidates wheels from both workflows)
release-nightly:
name: Nightly & Stable GitHub Releases
needs: identifiers
runs-on: ubuntu-latest
# Only create releases for nightly and stable builds (explicit positive list)
if: |
github.event_name == 'workflow_run' &&
github.event.workflow_run.conclusion == 'success' &&
(needs.identifiers.outputs.release_type == 'nightly' || needs.identifiers.outputs.release_type == 'stable') &&
(github.event.workflow_run.name == 'wheels' || github.event.workflow_run.name == 'wheels-docker')
env:
RELEASE_TYPE: ${{ needs.identifiers.outputs.release_type }}
RELEASE_NAME: ${{ needs.identifiers.outputs.release_name }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Download all wheel artifacts (from wheels workflow)
uses: actions/download-artifact@v4
with:
pattern: wheels-*
merge-multiple: true
path: dist/
continue-on-error: true
- name: Download source distribution
uses: actions/download-artifact@v4
with:
name: source-distribution
path: dist/
continue-on-error: true
- name: Download Linux wheels without NVX
uses: actions/download-artifact@v4
with:
name: linux-wheels-no-nvx
path: dist/
continue-on-error: true
- name: Download manylinux wheel artifacts (from wheels-docker workflow)
uses: actions/download-artifact@v4
with:
pattern: artifacts-*
merge-multiple: true
path: wheelhouse/
continue-on-error: true
- name: Consolidate all artifacts
run: |
echo "==> Consolidating all wheel artifacts into unified release directory..."
mkdir -p release-artifacts
# Copy from wheels workflow
if [ -d "dist" ]; then
echo "Copying wheels workflow artifacts..."
find dist -type f \( -name "*.whl" -o -name "*.tar.gz" \) -exec cp {} release-artifacts/ \;
fi
# Copy from wheels-docker workflow
if [ -d "wheelhouse" ]; then
echo "Copying wheels-docker workflow artifacts..."
find wheelhouse -type f \( -name "*.whl" -o -name "*.tar.gz" \) -exec cp {} release-artifacts/ \;
fi
echo ""
echo "==> Unified release artifact inventory:"
ls -la release-artifacts/ || echo "No artifacts found"
echo ""
echo "Total wheels: $(find release-artifacts -name "*.whl" | wc -l)"
echo "Source dists: $(find release-artifacts -name "*.tar.gz" | wc -l)"
- name: Install jinja2-cli for template rendering
run: |
pip install jinja2-cli
- name: Render release notes from Jinja2 template
run: |
echo "==> Preparing release notes using Jinja2 template..."
echo "Release type: $RELEASE_TYPE"
echo "Release name: $RELEASE_NAME"
# Collect template variables
COMMIT_SHA="${GITHUB_SHA::8}"
BUILD_DATE="$(date -u +'%Y-%m-%d %H:%M:%S UTC')"
WHEEL_COUNT="$(find release-artifacts -name "*.whl" | wc -l)"
SDIST_COUNT="$(find release-artifacts -name "*.tar.gz" | wc -l)"
# Select template based on release type
if [ "$RELEASE_TYPE" = "stable" ]; then
TEMPLATE=".github/templates/release-stable.md.j2"
else
TEMPLATE=".github/templates/release-nightly.md.j2"
fi
# Render template using jinja2
jinja2 "$TEMPLATE" \
-D release_name="$RELEASE_NAME" \
-D commit_sha="$COMMIT_SHA" \
-D build_date="$BUILD_DATE" \
-D wheel_count="$WHEEL_COUNT" \
-D sdist_count="$SDIST_COUNT" \
-o release-notes.md
echo ""
echo "==> Generated release notes:"
cat release-notes.md
- name: Create unified GitHub release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "==> Creating unified GitHub release..."
echo "Release type: $RELEASE_TYPE"
echo "Release name: $RELEASE_NAME"
# Delete existing release if it exists (for nightly builds)
gh release delete "$RELEASE_NAME" --repo "$GITHUB_REPOSITORY" --yes || true
# Set release title based on type
if [ "$RELEASE_TYPE" = "stable" ]; then
TITLE="Release $RELEASE_NAME"
else
TITLE="Nightly Build $RELEASE_NAME"
fi
# Create the release using rendered notes
gh release create "$RELEASE_NAME" \
--repo "$GITHUB_REPOSITORY" \
--title "$TITLE" \
--notes-file release-notes.md \
release-artifacts/*
echo "✅ Release $RELEASE_NAME created successfully"
# Stable release publishing: PyPI and RTD (consolidates from both wheel workflows)
release-stable:
name: Stable Release (PyPI & RTD)
needs: [identifiers, release-nightly]
runs-on: ubuntu-latest
# Only publish to PyPI for stable releases (explicit positive list)
if: needs.identifiers.outputs.release_type == 'stable'
env:
RELEASE_TYPE: ${{ needs.identifiers.outputs.release_type }}
RELEASE_NAME: ${{ needs.identifiers.outputs.release_name }}
environment:
name: pypi
url: https://pypi.org/p/autobahn
permissions:
id-token: write # For trusted publishing
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Download macOS wheels
uses: actions/download-artifact@v4
with:
name: wheels-macos-arm64
path: dist/
continue-on-error: true
- name: Download Windows wheels
uses: actions/download-artifact@v4
with:
name: wheels-windows-x86_64
path: dist/
continue-on-error: true
- name: Download source distribution
uses: actions/download-artifact@v4
with:
name: source-distribution
path: dist/
continue-on-error: true
- name: Download Linux wheels without NVX
uses: actions/download-artifact@v4
with:
name: linux-wheels-no-nvx
path: dist/
continue-on-error: true
- name: Download manylinux wheels with NVX (from wheels-docker)
uses: actions/download-artifact@v4
with:
pattern: artifacts-*
merge-multiple: true
path: dist/
continue-on-error: true
- name: List artifacts for PyPI publishing
run: |
echo "Publishing to PyPI for release: $RELEASE_NAME"
ls -la dist/
echo ""
echo "macOS wheels: $(find dist -name "*macos*.whl" 2>/dev/null | wc -l)"
echo "Windows wheels: $(find dist -name "*win*.whl" 2>/dev/null | wc -l)"
echo "Linux manylinux wheels: $(find dist -name "*manylinux*.whl" 2>/dev/null | wc -l)"
echo "Linux fallback wheels: $(find dist -name "*linux*.whl" ! -name "*manylinux*.whl" 2>/dev/null | wc -l)"
echo "Source distributions: $(find dist -name "*.tar.gz" 2>/dev/null | wc -l)"
echo ""
echo "Total PyPI artifacts: $(find dist -type f \( -name "*.whl" -o -name "*.tar.gz" \) | wc -l)"
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
# Uses trusted publishing - no API token needed
# Configure at: https://pypi.org/manage/account/publishing/
verbose: true
- name: Trigger RTD build
env:
RTD_TOKEN: ${{ secrets.RTD_TOKEN }}
run: |
if [ -n "$RTD_TOKEN" ]; then
echo "Triggering Read the Docs build for autobahn..."
curl -X POST \
-H "Authorization: Token $RTD_TOKEN" \
"https://readthedocs.org/api/v3/projects/autobahn/versions/latest/builds/"
echo "✅ RTD build triggered successfully"
else
echo "⚠️ RTD_TOKEN not configured, skipping RTD build trigger"
fi
# Development release: Post PR summary comment for development builds
release-development:
name: Development Release (PR Summary)
needs: identifiers
runs-on: ubuntu-latest
# Only run for PR/development contexts via workflow_run (has write permissions + artifact access)
if: |
github.event_name == 'workflow_run' &&
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.conclusion == 'success' &&
needs.identifiers.outputs.release_type == 'development'
env:
BASE_REPO: ${{ needs.identifiers.outputs.base_repo }}
BASE_BRANCH: ${{ needs.identifiers.outputs.base_branch }}
PR_NUMBER: ${{ needs.identifiers.outputs.pr_number }}
PR_REPO: ${{ needs.identifiers.outputs.pr_repo }}
PR_BRANCH: ${{ needs.identifiers.outputs.pr_branch }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Get PR information
id: pr-info
uses: actions/github-script@v7
with:
script: |
let pr_number, head_repo, head_ref;
if (context.eventName === 'workflow_dispatch') {
// Manual dispatch - get PR info from input
pr_number = context.payload.inputs.pr_number;
const { data: pr } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr_number
});
head_repo = pr.head.repo.full_name;
head_ref = pr.head.ref;
} else if (context.eventName === 'pull_request_target') {
// pull_request_target trigger - get PR info from event
pr_number = context.payload.pull_request.number;
head_repo = context.payload.pull_request.head.repo.full_name;
head_ref = context.payload.pull_request.head.ref;
} else {
// workflow_run trigger - get PR info from workflow_run event
const prs = context.payload.workflow_run.pull_requests;
if (!prs || prs.length === 0) {
core.setFailed('No PR found in workflow_run event');
return;
}
pr_number = prs[0].number;
head_repo = prs[0].head.repo.full_name;
head_ref = prs[0].head.ref;
}
console.log(`PR: #${pr_number}, Repo: ${head_repo}, Branch: ${head_ref}`);
// Set outputs for next steps
core.setOutput('pr_number', pr_number);
core.setOutput('head_repo', head_repo);
core.setOutput('head_ref', head_ref);
- name: Download wstest conformance summary
uses: actions/download-artifact@v4
with:
name: conformance-summary-${{ github.event.workflow_run.conclusion == 'success' && 'quick' || env.TEST_MODE || 'quick' }}
run-id: ${{ github.event.workflow_run.id }}
path: summary-artifact/
continue-on-error: true
- name: Install jinja2-cli for template rendering
run: |
pip install jinja2-cli
- name: Render PR comment from Jinja2 template
id: render
run: |
echo "==> Preparing PR comment using Jinja2 template..."
# Collect template variables
PR_NUMBER="${{ steps.pr-info.outputs.pr_number }}"
PR_REPO="${{ steps.pr-info.outputs.head_repo }}"
PR_BRANCH="${{ steps.pr-info.outputs.head_ref }}"
BASE_REPO="${BASE_REPO}"
BASE_BRANCH="${BASE_BRANCH}"
COMMIT_SHA="${GITHUB_SHA::8}"
BUILD_DATE="$(date -u +'%Y-%m-%d %H:%M:%S UTC')"
WORKFLOW_RUN_URL="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
# Read wstest summary if available, otherwise use placeholder
WSTEST_SUMMARY="WebSocket conformance testing results not available."
SUMMARY_FILE=$(find summary-artifact/ -name "*wstest-summary.md" 2>/dev/null | head -1)
if [[ -n "$SUMMARY_FILE" && -f "$SUMMARY_FILE" ]]; then
echo "✅ Found wstest summary: $SUMMARY_FILE"
WSTEST_SUMMARY=$(cat "$SUMMARY_FILE")
WHEEL_COUNT=$(find . -name "*.whl" 2>/dev/null | wc -l)
else
echo "⚠️ No wstest summary found, using placeholder"
WHEEL_COUNT="N/A"
fi
# Render template using jinja2
jinja2 .github/templates/release-development.md.j2 \
-D pr_number="$PR_NUMBER" \
-D pr_repo="$PR_REPO" \
-D pr_branch="$PR_BRANCH" \
-D base_repo="$BASE_REPO" \
-D base_branch="$BASE_BRANCH" \
-D commit_sha="$COMMIT_SHA" \
-D build_date="$BUILD_DATE" \
-D workflow_run_url="$WORKFLOW_RUN_URL" \
-D wheel_count="$WHEEL_COUNT" \
-D wstest_summary="$WSTEST_SUMMARY" \
-o pr-comment.md
echo ""
echo "==> Generated PR comment:"
cat pr-comment.md
# Check if we should post comment
if [[ -n "$SUMMARY_FILE" && -f "$SUMMARY_FILE" ]]; then
echo "should_comment=true" >> $GITHUB_OUTPUT
else
echo "should_comment=false" >> $GITHUB_OUTPUT
fi
- name: Post PR comment using GitHub CLI
if: steps.render.outputs.should_comment == 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "==> Posting comment to PR #${{ steps.pr-info.outputs.pr_number }}..."
gh pr comment "${{ steps.pr-info.outputs.pr_number }}" \
--repo "$GITHUB_REPOSITORY" \
--body-file pr-comment.md
echo "✅ PR comment posted successfully"
- name: Skip PR comment
if: steps.render.outputs.should_comment == 'false'
run: |
echo "ℹ️ Skipping PR comment - wstest summary not available"