Skip to content

Commit d5217fd

Browse files
zhangskzalexeagle
andauthored
feat: update bazel central registry publish workflow (#23465) (#23913)
Includes pre-built protoc integrity hashes in the release artifact, in a new file `bazel/private/prebuilt_tool_integrity.bzl` tested on my fork of protobuf: https://github.com/alexeagle/protobuf/releases/tag/v0.1000.10 Next steps: - create toolchain definitions that fetch the prebuilt protoc from github releases - change logic in Bazel setup to use the prebuilt toolchain when desired - create a token from @protobuf-team-bot account and add to GHA secrets so the pull request to BCR opens Closes #23465 COPYBARA_INTEGRATE_REVIEW=#23465 from protocolbuffers:alexeagle/bazel-protoc-prebuilt 05314db PiperOrigin-RevId: 817227717 Co-authored-by: Alex Eagle <alex@aspect.dev>
1 parent d1627e2 commit d5217fd

File tree

6 files changed

+147
-1
lines changed

6 files changed

+147
-1
lines changed

‎.bcr/source.template.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"integrity": "**leave this alone**",
33
"strip_prefix": "{REPO}-{VERSION}",
4-
"url": "https://github.com/{OWNER}/{REPO}/releases/download/{TAG}/{REPO}-{VERSION}.zip"
4+
"url": "https://github.com/{OWNER}/{REPO}/releases/download/{TAG}/{REPO}-{VERSION}.tar.gz"
55
}

‎.gitattributes‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Configuration for 'git archive'
2+
# see https://git-scm.com/docs/git-archive/2.40.0#ATTRIBUTES
3+
# Don't include compatibility folder in the distribution artifact, just to reduce size
4+
compatibility/ export-ignore
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Publish new releases to Bazel Central Registry.
2+
name: Publish to BCR
3+
on:
4+
# Run the publish workflow after a successful release
5+
# Will be triggered from the release.yaml workflow
6+
workflow_call:
7+
inputs:
8+
tag_name:
9+
required: true
10+
type: string
11+
secrets:
12+
# This token should be owned by https://github.com/protobuf-team-bot
13+
BCR_PUBLISH_TOKEN:
14+
required: true
15+
# In case of problems, let release engineers retry by manually dispatching
16+
# the workflow from the GitHub UI
17+
workflow_dispatch:
18+
inputs:
19+
tag_name:
20+
description: git tag being released
21+
required: true
22+
type: string
23+
jobs:
24+
publish:
25+
uses: bazel-contrib/publish-to-bcr/.github/workflows/publish.yaml@v1.0.0
26+
with:
27+
tag_name: ${{ inputs.tag_name }}
28+
# GitHub repository which is a fork of the upstream where the Pull Request will be opened.
29+
registry_fork: protocolbuffers/bazel-central-registry
30+
permissions:
31+
attestations: write
32+
contents: write
33+
id-token: write
34+
secrets:
35+
# Necessary to push to the BCR fork, and to open a pull request against a registry
36+
publish_token: ${{ secrets.BCR_PUBLISH_TOKEN }}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Prepare a release specifically for Bazel users, including a pre-built protoc.
2+
name: Bazel Release
3+
on:
4+
# Can be triggered from the GitHub Actions ui, using the "Run workflow" button on
5+
# https://github.com/protocolbuffers/protobuf/actions/workflows/release_bazel_module.yaml
6+
# TODO: consider automating the trigger from a new release being created
7+
workflow_dispatch:
8+
inputs:
9+
tag_name:
10+
description: git tag that has the protoc release artifact
11+
required: true
12+
type: string
13+
permissions:
14+
id-token: write
15+
attestations: write
16+
contents: write
17+
jobs:
18+
release:
19+
uses: bazel-contrib/.github/.github/workflows/release_ruleset.yaml@v7.2.3
20+
with:
21+
release_files: protobuf-*.tar.gz
22+
prerelease: false
23+
tag_name: ${{ inputs.tag_name }}
24+
# The release was already created by Google-internal mechanism,
25+
# so there aren't any useful assertions to make here.
26+
bazel_test_command: 'true'
27+
publish:
28+
needs: release
29+
uses: ./.github/workflows/publish_to_bcr.yaml
30+
with:
31+
tag_name: ${{ inputs.tag_name }}
32+
secrets:
33+
BCR_PUBLISH_TOKEN: ${{ secrets.BCR_PUBLISH_TOKEN }}

‎.github/workflows/release_prep.sh‎

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/usr/bin/env bash
2+
# NB: this file must be named release_prep.sh because the attestation generation doesn't trust user control.
3+
# see https://github.com/bazel-contrib/.github/blob/v7.2.3/.github/workflows/release_ruleset.yaml#L33-L45
4+
set -o errexit -o nounset -o pipefail
5+
6+
# Argument provided by reusable workflow caller, see
7+
# https://github.com/bazel-contrib/.github/blob/v7.2.3/.github/workflows/release_ruleset.yaml#L104
8+
TAG=$1
9+
PREFIX="protobuf-${TAG:1}"
10+
ARCHIVE="$PREFIX.tar.gz"
11+
ARCHIVE_TMP=$(mktemp)
12+
INTEGRITY_FILE=${PREFIX}/bazel/private/prebuilt_tool_integrity.bzl
13+
14+
# NB: configuration for 'git archive' is in /.gitattributes
15+
git archive --format=tar --prefix=${PREFIX}/ ${TAG} > $ARCHIVE_TMP
16+
############
17+
# Patch up the archive to have integrity hashes for built binaries that we downloaded in the GHA workflow.
18+
# Now that we've run `git archive` we are free to pollute the working directory.
19+
20+
# Delete the placeholder file
21+
tar --file $ARCHIVE_TMP --delete $INTEGRITY_FILE
22+
23+
# Use jq to translate GitHub Releases json into a Starlark object
24+
filter_releases=$(cat <<'EOF'
25+
# Read the file assets already present on the release
26+
reduce .assets[] as $a (
27+
# Start with an empty dictionary, and for each asset, add
28+
{}; . + {
29+
# The format required in starlark, i.e. "release-name": "deadbeef123"
30+
($a.name): ($a.digest | sub("^sha256:"; ""))
31+
}
32+
)
33+
EOF
34+
)
35+
36+
mkdir -p ${PREFIX}/bazel/private
37+
cat >${INTEGRITY_FILE} <<EOF
38+
"Generated during release by release_prep.sh"
39+
40+
RELEASED_BINARY_INTEGRITY = $(
41+
curl -s https://api.github.com/repos/protocolbuffers/protobuf/releases/tags/${TAG} \
42+
| jq -f <(echo "$filter_releases")
43+
)
44+
EOF
45+
46+
# Append that generated file back into the archive
47+
tar --file $ARCHIVE_TMP --append ${INTEGRITY_FILE}
48+
49+
# END patch up the archive
50+
############
51+
52+
gzip < $ARCHIVE_TMP > $ARCHIVE
53+
SHA=$(shasum -a 256 $ARCHIVE | awk '{print $1}')
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
"""Release binary integrity hashes.
2+
3+
This file contents are entirely replaced during release publishing, by .github/workflows/release_prep.sh
4+
so that the integrity of the prebuilt tools is included in the release artifact.
5+
6+
The checked in content is only here to allow load() statements in the sources to resolve.
7+
"""
8+
9+
# Create a mapping for every tool name to the hash of /dev/null
10+
NULLSHA = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
11+
RELEASED_BINARY_INTEGRITY = {
12+
"-".join([
13+
"protoc",
14+
os,
15+
arch,
16+
]): NULLSHA
17+
for [os, arch] in {
18+
"linux": ["aarch_64", "x86_64"],
19+
}
20+
}

0 commit comments

Comments
 (0)