Skip to content

Commit cb14a0a

Browse files
authored
Create separate protoc releases (#1837)
# Motivation In a previous PR, I added a Github workflow and scripts to attach a protoc artifactbundle to the latest draft release. This created a chicken and egg problem since we needed to reference the protoc URL in our Package.swift but the URL wasn't public until we published a release. # Modifications This PR changes the workflow and script so that we create separate protoc-artifactbundle releases with a separate tagging scheme that won't conflict with our normal tags. These releases are only used to distribute protoc artifactbundles. # Result We can now generate the protoc artifactbundle releases that we can reference in our Package.swift without creating this chicken and egg problem.
1 parent 70f9e85 commit cb14a0a

File tree

4 files changed

+113
-72
lines changed

4 files changed

+113
-72
lines changed

.github/scripts/upload_artifactbundle.sh renamed to .github/scripts/draft_release_protoc_artifactbundle.sh

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22

33
# This script generates an artifactbundle for protoc. This artifactbundle
44
# is used by the Swift package manger. The script is run by a GitHub action
5-
# when a new pre-release is created for swift-protobuf.
5+
# to create protoc-vXXX releases with artifactbundles.
66

77
set -eux
88

9-
# Fetch the latest stable release from protocolbuffers/protobuf
109
AUTH="Authorization: token $GITHUB_TOKEN"
11-
response=$(curl -sH "$AUTH" "https://api.github.com/repos/protocolbuffers/protobuf/releases/latest")
12-
TAG=$(echo "$response" | grep -m 1 '"tag_name":' | cut -d '"' -f 4)
10+
11+
# Fetch the latest stable release from protocolbuffers/protobuf
12+
upstream_response=$(curl -sH "$AUTH" "https://api.github.com/repos/protocolbuffers/protobuf/releases/latest")
13+
TAG=$(echo "$upstream_response" | grep -m 1 '"tag_name":' | cut -d '"' -f 4)
1314

1415
# Remove 'v' prefix if present
1516
TAG="${TAG#v}"
@@ -19,6 +20,29 @@ if [[ ! "$TAG" =~ ^[0-9]+\.[0-9]+$ ]]; then
1920
exit 1
2021
fi
2122

23+
echo "Latest upstream protoc version: $TAG"
24+
25+
# Check for the latest protoc-vXXX release in this swift-protobuf repo
26+
swift_protobuf_response=$(curl -sH "$AUTH" "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/releases")
27+
CURRENT_PROTOC_TAG=$(echo "$swift_protobuf_response" | jq -r '.[] | select(.tag_name | startswith("protoc-v")) | .tag_name' | head -n 1)
28+
29+
if [ -z "$CURRENT_PROTOC_TAG" ] || [ "$CURRENT_PROTOC_TAG" = "null" ]; then
30+
echo "No existing protoc-vXXX release found. This will be the initial release."
31+
CURRENT_PROTOC_VERSION=""
32+
else
33+
# Extract version from protoc-vX.Y format
34+
CURRENT_PROTOC_VERSION="${CURRENT_PROTOC_TAG#protoc-v}"
35+
echo "Current swift-protobuf protoc version: $CURRENT_PROTOC_VERSION"
36+
fi
37+
38+
# Compare versions - if they match, no need to create a new release
39+
if [ "$CURRENT_PROTOC_VERSION" = "$TAG" ]; then
40+
echo "Protoc version $TAG is already released. No action needed."
41+
exit 0
42+
fi
43+
44+
echo "Creating new protoc release: protoc-v$TAG"
45+
2246
# Fetch all protoc release assets from protocolbuffers/protobuf
2347
curl -LJ --output protoc-$TAG-osx-x86_64.zip -H 'Accept: application/octet-stream' https://github.com/protocolbuffers/protobuf/releases/download/v$TAG/protoc-$TAG-osx-x86_64.zip
2448
curl -LJ --output protoc-$TAG-osx-aarch_64.zip -H 'Accept: application/octet-stream' https://github.com/protocolbuffers/protobuf/releases/download/v$TAG/protoc-$TAG-osx-aarch_64.zip
@@ -85,20 +109,35 @@ EOF
85109
# Zip artifactbundle
86110
zip -r protoc-$TAG.artifactbundle.zip protoc-$TAG.artifactbundle
87111

88-
# Get asset upload url for the latest swift-protobuf draft release
89-
response=$(curl -sH "$AUTH" "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/releases")
90-
upload_url=$(echo "$response" | jq -r '.[] | select(.draft == true) | .upload_url' | head -n 1)
91-
SWIFT_PROTOBUF_TAG=$(echo "$response" | jq -r '.[] | select(.draft == true) | .tag_name' | head -n 1)
92-
93-
if [ -z "$SWIFT_PROTOBUF_TAG" ] || [ -z "$upload_url" ]; then
94-
echo "Error: No draft release found"
112+
# Create a new draft release for protoc-vXXX
113+
echo "Creating draft release protoc-v$TAG"
114+
create_response=$(curl -sH "$AUTH" -X POST "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/releases" \
115+
-d "{
116+
\"tag_name\": \"protoc-artifactbundle-v$TAG\",
117+
\"name\": \"protoc v$TAG artifactbundle\",
118+
\"body\": \"Protoc artifactbundle for version $TAG\",
119+
\"draft\": true,
120+
\"prerelease\": false,
121+
\"make_latest\": false
122+
}")
123+
124+
upload_url=$(echo "$create_response" | jq -r '.upload_url')
125+
release_id=$(echo "$create_response" | jq -r '.id')
126+
127+
if [ -z "$upload_url" ] || [ "$upload_url" = "null" ] || [ -z "$release_id" ] || [ "$release_id" = "null" ]; then
128+
echo "Error: Failed to create draft release"
129+
echo "Response: $create_response"
95130
exit 1
96131
fi
97132

98133
# Remove the {?name,label} template from upload_url
99134
upload_url=$(echo "$upload_url" | sed 's/{?name,label}//')
100-
echo "Found draft release: $SWIFT_PROTOBUF_TAG"
135+
echo "Created draft release with ID: $release_id"
101136
echo "Upload URL: $upload_url"
102137

103138
# Upload asset
104-
curl --data-binary @protoc-$TAG.artifactbundle.zip -H "$AUTH" -H "Content-Type: application/octet-stream" "$upload_url?name=protoc-$TAG.artifactbundle.zip"
139+
echo "Uploading artifactbundle..."
140+
upload_response=$(curl --data-binary @protoc-$TAG.artifactbundle.zip -H "$AUTH" -H "Content-Type: application/octet-stream" "$upload_url?name=protoc-$TAG.artifactbundle.zip")
141+
142+
echo "Upload completed successfully!"
143+
echo "Draft release protoc-v$TAG created with artifactbundle"
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: Draft release protoc artifactbundle
2+
3+
on:
4+
workflow_dispatch:
5+
6+
jobs:
7+
draft-release:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- name: "Checkout code"
11+
uses: actions/checkout@v4
12+
- name: Draft release and upload artifactbundle
13+
env:
14+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
15+
run: cd ${{ github.workspace }} && .github/scripts/draft_release_protoc_artifactbundle.sh
16+

.github/workflows/prerelease_protoc_artifactbundle.yml

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

Documentation/RELEASING.md

Lines changed: 45 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@
22

33
---
44

5-
When doing a release:
5+
This document covers two types of releases:
6+
7+
1. **Swift Protobuf Library Releases** - New versions of the Swift protobuf library itself
8+
2. **Protoc Artifactbundle Releases** - Updates to the bundled protoc compiler when new protoc versions are available
9+
10+
## Swift Protobuf Library Releases
11+
12+
When doing a Swift Protobuf library release:
613

714
1. Examine what has changed
815

@@ -48,48 +55,6 @@ When doing a release:
4855
everything based on the PR descriptions and _semver_ tags in the repo. Just read
4956
though was was generate to see if any tweaks are needed.
5057

51-
**Important:** Save this as a **draft** release first (do not publish yet).
52-
53-
1. Generate protoc artifact bundle if needed
54-
55-
First, check if there have been any new protoc releases since the last
56-
time we bundled protoc. To do this check the binary target protoc version number
57-
in the Package.swift. If there has been a new release of protoc then once you
58-
have created the draft release, trigger the "Upload protoc artifactbundle"
59-
workflow from the [Actions tab](https://github.com/apple/swift-protobuf/actions/workflows/prerelease_protoc_artifactbundle.yml).
60-
61-
This workflow will:
62-
- Fetch the latest stable protoc release from protocolbuffers/protobuf
63-
- Create a Swift Package Manager compatible artifact bundle
64-
- Upload it to your draft release
65-
66-
Wait for the workflow to complete successfully before proceeding.
67-
68-
1. Update Package.swift with new artifact bundle
69-
70-
If there was a new protoc release and you uploaded a new artifact bundle in
71-
the previous step. Create a pull request that updates the `Package.swift` file
72-
to reference the new artifact bundle. You'll need to update two things:
73-
74-
- **URL**: Change to point to your new release tag
75-
- **Checksum**: Download the artifact bundle and calculate its SHA256 hash
76-
77-
Example update:
78-
```swift
79-
.binaryTarget(
80-
name: "protoc",
81-
url: "https://github.com/apple/swift-protobuf/releases/download/[a.b.c]/protoc-X.Y.artifactbundle.zip",
82-
checksum: "new-sha256-checksum-here"
83-
),
84-
```
85-
86-
To get the checksum copy it from the Github UI when looking at the draft release.bundle.zip
87-
88-
1. Publish the release
89-
90-
After the Package.swift PR is merged, return to your draft release and click
91-
_Publish release_.
92-
9358
1. Publish the `SwiftProtobuf.podspec`
9459

9560
_Note:_ You must be an _owner_ of the pod to do this, see `pod trunk info SwiftProtobuf`
@@ -101,3 +66,40 @@ When doing a release:
10166
10267
_Note:_ This uses that local copy of `SwiftProtobuf.podspec`, but checks
10368
against the sources on github.
69+
70+
## Protoc Artifactbundle Releases
71+
72+
Protoc artifactbundle releases are independent of Swift Protobuf library releases and follow
73+
a `protoc-vX.Y` naming convention that matches the upstream protoc version.
74+
75+
### Creating a protoc release
76+
77+
1. **Trigger the workflow**
78+
79+
Go to the [Actions tab](https://github.com/apple/swift-protobuf/actions/workflows/draft_release_protoc_artifactbundle.yml)
80+
and manually run the "Draft release protoc artifactbundle" workflow.
81+
82+
2. **What the workflow does automatically**
83+
84+
The workflow will:
85+
- Check the latest protoc version from protocolbuffers/protobuf
86+
- Check if we already have a matching `protoc-vX.Y` release
87+
- If versions differ or no release exists:
88+
- Download protoc binaries for all supported platforms
89+
- Create a Swift Package Manager compatible artifact bundle
90+
- Create a new draft release tagged `protoc-vX.Y`
91+
- Upload the artifactbundle to the draft release
92+
- If versions match, exit early (no action needed)
93+
94+
3. **Publish the release**
95+
96+
After the workflow completes successfully:
97+
- Go to the [releases page](https://github.com/apple/swift-protobuf/releases)
98+
- Find the draft `protoc-vX.Y` release
99+
- Review the release notes and artifactbundle
100+
- Click "Publish release"
101+
102+
4. **Use in Swift Protobuf**
103+
104+
The protoc release is now available with a stable URL that can be referenced
105+
in `Package.swift`. Create a separate PR to update the reference in the `Package.swift`

0 commit comments

Comments
 (0)