Skip to content

Commit e2cd7ad

Browse files
authored
Consolidate SDK GitHub releases (#2305)
* Consolidate SDK GitHub releases Create one shared GitHub Release for all SDK languages while retaining scoped Rust and Java source tags. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 01a9d0e3-0073-48f2-afae-de0398986669 * Gate releases on Maven publication Expose Maven publication success from the reusable Java workflow so documentation deployment failures do not suppress the shared SDK release. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 01a9d0e3-0073-48f2-afae-de0398986669 * Clarify unified release guidance Document the Node-only unstable channel and align changelog examples with the six-language release policy. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 01a9d0e3-0073-48f2-afae-de0398986669 --------- Copilot-Session: 01a9d0e3-0073-48f2-afae-de0398986669
1 parent 3108e8c commit e2cd7ad

8 files changed

Lines changed: 44 additions & 189 deletions

File tree

.github/workflows/java-publish-maven.yml

Lines changed: 7 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ on:
3737
type: boolean
3838
required: false
3939
default: false
40+
outputs:
41+
mavenPublished:
42+
description: "Whether the Java package was published to Maven Central"
43+
value: ${{ jobs.publish-maven.outputs.published }}
4044
secrets:
4145
JAVA_RELEASE_TOKEN:
4246
required: true
@@ -80,39 +84,6 @@ jobs:
8084
env:
8185
GITHUB_TOKEN: ${{ secrets.JAVA_RELEASE_TOKEN }}
8286

83-
- name: Verify JAVA_RELEASE_GITHUB_TOKEN can trigger workflows
84-
run: |
85-
# JAVA_RELEASE_GITHUB_TOKEN is used for:
86-
# - gh workflow run release-changelog.lock.yml (requires actions:write)
87-
# Check the token's OAuth scopes for 'workflow' (classic PAT) or
88-
# attempt a workflow dispatch with a non-existent ref to verify write access
89-
# (fine-grained PAT — these don't expose scopes via X-OAuth-Scopes).
90-
SCOPES=$(gh api -i user 2>&1 | grep -i '^x-oauth-scopes:' | tr '[:upper:]' '[:lower:]' || true)
91-
if echo "$SCOPES" | grep -q 'workflow'; then
92-
echo "JAVA_RELEASE_GITHUB_TOKEN has 'workflow' scope (classic PAT)"
93-
elif [ -z "$SCOPES" ]; then
94-
# Fine-grained PAT: no X-OAuth-Scopes header returned.
95-
# Attempt a workflow dispatch against a non-existent ref. If the token
96-
# has actions:write, the API returns 422 (validation failed on ref).
97-
# If it lacks the permission, the API returns 403.
98-
HTTP_CODE=$(gh api -X POST \
99-
"repos/${{ github.repository }}/actions/workflows/release-changelog.lock.yml/dispatches" \
100-
-f ref="preflight-check-nonexistent-ref" \
101-
-f 'inputs[tag]=preflight-check' \
102-
--silent -i 2>&1 | head -1 | grep -oE '[0-9]{3}' || echo "000")
103-
if [ "$HTTP_CODE" = "403" ] || [ "$HTTP_CODE" = "000" ]; then
104-
echo "::error::JAVA_RELEASE_GITHUB_TOKEN lacks actions:write permission on ${{ github.repository }}. It cannot trigger the changelog generation workflow."
105-
exit 1
106-
fi
107-
# 422 = has write access but ref doesn't exist (expected), 204 would mean it dispatched (shouldn't happen with fake ref)
108-
echo "JAVA_RELEASE_GITHUB_TOKEN actions:write access OK (fine-grained PAT, dispatch returned HTTP ${HTTP_CODE})"
109-
else
110-
echo "::error::JAVA_RELEASE_GITHUB_TOKEN lacks 'workflow' scope. Found scopes: ${SCOPES}. It needs this scope to trigger changelog generation via gh workflow run."
111-
exit 1
112-
fi
113-
env:
114-
GITHUB_TOKEN: ${{ secrets.JAVA_RELEASE_GITHUB_TOKEN }}
115-
11687
publish-maven:
11788
name: Publish Java SDK to Maven Central
11889
needs: preflight
@@ -123,6 +94,7 @@ jobs:
12394
working-directory: ./java
12495
outputs:
12596
version: ${{ steps.versions.outputs.release_version }}
97+
published: ${{ steps.publish-maven.outcome == 'success' }}
12698
steps:
12799
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
128100
with:
@@ -227,6 +199,7 @@ jobs:
227199
JAVA_GPG_PASSPHRASE: ${{ secrets.JAVA_GPG_PASSPHRASE }}
228200

229201
- name: Perform Release and Deploy to Maven Central
202+
id: publish-maven
230203
working-directory: ./java
231204
run: |
232205
mvn -B release:perform \
@@ -248,68 +221,9 @@ jobs:
248221
# Also run Maven release:rollback to clean up any partial release state
249222
mvn -B release:rollback || true
250223
251-
github-release:
252-
name: Create GitHub Release
253-
needs: [preflight, publish-maven]
254-
if: github.ref == 'refs/heads/main'
255-
runs-on: ubuntu-latest
256-
defaults:
257-
run:
258-
shell: bash
259-
working-directory: ./java
260-
steps:
261-
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
262-
with:
263-
fetch-depth: 0
264-
- name: Create GitHub Release
265-
run: |
266-
VERSION="${{ needs.publish-maven.outputs.version }}"
267-
GROUP_ID="com.github"
268-
ARTIFACT_ID="copilot-sdk-java"
269-
CURRENT_TAG="java/v${VERSION}"
270-
271-
if gh release view "${CURRENT_TAG}" >/dev/null 2>&1; then
272-
echo "Release ${CURRENT_TAG} already exists. Skipping creation."
273-
exit 0
274-
fi
275-
276-
# Generate release notes from template
277-
export VERSION GROUP_ID ARTIFACT_ID
278-
RELEASE_NOTES=$(envsubst < $GITHUB_WORKSPACE/.github/workflows/java.notes.template)
279-
280-
# Get the previous tag for generating notes
281-
# grep returns exit 1 when no lines match (first release), so
282-
# append "|| true" to prevent pipefail from aborting the script.
283-
PREV_TAG=$(git tag --list 'java/v*' --sort=-version:refname \
284-
| grep -Fxv "${CURRENT_TAG}" \
285-
| head -n 1 || true)
286-
287-
echo "Current tag: ${CURRENT_TAG}"
288-
echo "Previous tag: ${PREV_TAG}"
289-
290-
# Build the gh release command
291-
GH_ARGS=("${CURRENT_TAG}")
292-
GH_ARGS+=("--title" "GitHub Copilot SDK for Java ${VERSION}")
293-
GH_ARGS+=("--notes" "${RELEASE_NOTES}")
294-
GH_ARGS+=("--generate-notes")
295-
296-
if [ -n "$PREV_TAG" ]; then
297-
GH_ARGS+=("--notes-start-tag" "$PREV_TAG")
298-
fi
299-
300-
${{ inputs.prerelease == true && 'GH_ARGS+=("--prerelease")' || '' }}
301-
302-
gh release create "${GH_ARGS[@]}"
303-
env:
304-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
305-
- name: Trigger changelog generation
306-
run: gh workflow run release-changelog.lock.yml -f tag="java/v${{ needs.publish-maven.outputs.version }}"
307-
env:
308-
GITHUB_TOKEN: ${{ secrets.JAVA_RELEASE_GITHUB_TOKEN }}
309-
310224
deploy-site:
311225
name: Deploy Documentation Site
312-
needs: [preflight, publish-maven, github-release]
226+
needs: [preflight, publish-maven]
313227
if: github.ref == 'refs/heads/main'
314228
runs-on: ubuntu-latest
315229
steps:

.github/workflows/java.notes.template

Lines changed: 0 additions & 29 deletions
This file was deleted.

.github/workflows/publish.yml

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,8 @@ jobs:
379379
needs.publish-nodejs.result == 'success' &&
380380
needs.publish-dotnet.result == 'success' &&
381381
needs.publish-python.result == 'success' &&
382-
needs.publish-rust.result == 'success'
382+
needs.publish-rust.result == 'success' &&
383+
needs.publish-java.outputs.mavenPublished == 'true'
383384
runs-on: ubuntu-latest
384385
permissions:
385386
actions: write
@@ -434,11 +435,9 @@ jobs:
434435
fi
435436
env:
436437
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
437-
- name: Tag Rust SDK and create Rust GitHub Release
438-
# Rust gets its own version-scoped GitHub Release with notes
439-
# derived from PR titles since the previous Rust tag. The
440-
# cross-language `vX.Y.Z` release above still exists; this one
441-
# is the canonical reference for Rust users.
438+
- name: Tag Rust SDK
439+
# Keep a language-scoped source tag for traceability. Rust is
440+
# included in the cross-language `vX.Y.Z` GitHub Release.
442441
if: github.event.inputs.dist-tag == 'latest' || github.event.inputs.dist-tag == 'prerelease'
443442
run: |
444443
set -e
@@ -453,26 +452,5 @@ jobs:
453452
else
454453
echo "Tag $TAG_NAME already exists, skipping tag push"
455454
fi
456-
# Find the previous Rust tag for note generation. Prefer rust/v*,
457-
# fall back to the historical rust-v* tags from the release-plz era.
458-
PREV_TAG=$(git tag --list 'rust/v*' --sort=-v:refname | grep -vFx "$TAG_NAME" | head -n1)
459-
if [ -z "$PREV_TAG" ]; then
460-
PREV_TAG=$(git tag --list 'rust-v*' --sort=-v:refname | head -n1)
461-
fi
462-
NOTES_FLAG=""
463-
if [ -n "$PREV_TAG" ]; then
464-
NOTES_FLAG="--notes-start-tag $PREV_TAG"
465-
echo "Generating notes from $PREV_TAG..$TAG_NAME"
466-
else
467-
echo "No previous Rust tag found; generating notes from full history"
468-
fi
469-
PRERELEASE_FLAG=""
470-
if [ "${{ github.event.inputs.dist-tag }}" = "prerelease" ]; then
471-
PRERELEASE_FLAG="--prerelease"
472-
fi
473-
gh release create "$TAG_NAME" \
474-
--title "$TAG_NAME" \
475-
--generate-notes $NOTES_FLAG $PRERELEASE_FLAG \
476-
--target ${{ github.sha }}
477455
env:
478456
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/release-changelog.lock.yml

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)