Skip to content

Commit 0f983d2

Browse files
authored
Migrate to BzlMod (#7)
* Update js files for newer closure-compiler * Add MODULE.bazel and supporting files * mark tests manual * Add github CI * Use archive_override for io_bazel_rules_closure * Fix workspace name
1 parent 9523e67 commit 0f983d2

20 files changed

+2165
-113
lines changed

.bazelrc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
build --java_language_version=21
2+
build --java_runtime_version=21
3+
build --tool_java_language_version=21
4+
build --tool_java_runtime_version=21

.bazelversion

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
8.4.1

.github/workflows/ci.bazelrc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Debug where options came from
2+
build --announce_rc
3+
4+
# Don't rely on test logs being easily accessible from the test runner,
5+
# though it makes the log noisier.
6+
test --test_output=errors
7+
8+
# This directory is configured in GitHub actions to be persisted between runs.
9+
build --disk_cache=$HOME/.cache/bazel
10+
build --repository_cache=$HOME/.cache/bazel-repo
11+
build --repo_contents_cache=
12+
13+
# Allows tests to run bazelisk-in-bazel, since this is the cache folder used
14+
test --test_env=XDG_CACHE_HOME

.github/workflows/ci.yaml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: CI
2+
3+
# Controls when the action will run.
4+
on:
5+
push:
6+
branches: [master]
7+
pull_request:
8+
workflow_dispatch:
9+
10+
concurrency:
11+
# Cancel previous actions from the same PR: https://stackoverflow.com/a/72408109
12+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
13+
cancel-in-progress: true
14+
15+
jobs:
16+
test:
17+
runs-on: self-hosted
18+
steps:
19+
- uses: actions/checkout@v4
20+
- uses: bazel-contrib/setup-bazel@0.15.0
21+
with:
22+
# Avoid downloading Bazel every time.
23+
bazelisk-cache: true
24+
# Store build cache per workflow.
25+
disk-cache: true
26+
# Share repository cache between workflows.
27+
repository-cache: true
28+
- name: bazel build
29+
run: >-
30+
bazelisk
31+
--bazelrc=.github/workflows/ci.bazelrc
32+
--bazelrc=.bazelrc
33+
build
34+
...

.github/workflows/publish.yaml

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+
publish_token:
13+
required: true
14+
# In case of problems, let release engineers retry by manually dispatching
15+
# the workflow from the GitHub UI
16+
workflow_dispatch:
17+
inputs:
18+
tag_name:
19+
description: git tag being released
20+
required: true
21+
type: string
22+
jobs:
23+
publish:
24+
uses: bazel-contrib/publish-to-bcr/.github/workflows/publish.yaml@v0.2.3
25+
with:
26+
draft: false
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: stackb/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.publish_token || secrets.BCR_PUBLISH_TOKEN }}

.github/workflows/release.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Cut a release whenever a new tag is pushed to the repo.
2+
name: Release
3+
on:
4+
# Can be triggered from the tag.yaml workflow
5+
workflow_call:
6+
inputs:
7+
tag_name:
8+
required: true
9+
type: string
10+
secrets:
11+
publish_token:
12+
required: true
13+
# Or, developers can manually push a tag from their clone
14+
push:
15+
tags:
16+
- "v*.*.*"
17+
permissions:
18+
id-token: write
19+
attestations: write
20+
contents: write
21+
jobs:
22+
release:
23+
uses: bazel-contrib/.github/.github/workflows/release_ruleset.yaml@v7.2.3
24+
# uses: ./.github/workflows/release_ruleset.yaml # copied-from: bazel-contrib/.github/.github/workflows/release_ruleset.yaml@v7.2.3
25+
with:
26+
prerelease: false
27+
release_files: ui.js-*.tar.gz
28+
tag_name: ${{ inputs.tag_name || github.ref_name }}
29+
secrets: inherit
30+
publish:
31+
needs: release
32+
uses: ./.github/workflows/publish.yaml
33+
with:
34+
tag_name: ${{ inputs.tag_name || github.ref_name }}
35+
secrets:
36+
publish_token: ${{ secrets.publish_token || secrets.BCR_PUBLISH_TOKEN }}

.github/workflows/release_prep.sh

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
#!/usr/bin/env bash
3+
4+
set -o errexit -o nounset -o pipefail
5+
6+
# Set by GH actions, see
7+
# https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables
8+
readonly TAG=$1
9+
# The prefix is chosen to match what GitHub generates for source archives.
10+
# This guarantees that users can easily switch from a released artifact to a source archive
11+
# with minimal differences in their code (e.g. strip_prefix remains the same)
12+
readonly PREFIX="ui.js-${TAG}"
13+
readonly ARCHIVE="${PREFIX}.tar.gz"
14+
15+
# NB: configuration for 'git archive' is in /.gitattributes
16+
git archive --format=tar --prefix=${PREFIX}/ ${TAG} | gzip > $ARCHIVE
17+
SHA=$(shasum -a 256 $ARCHIVE | awk '{print $1}')
18+
19+
# The stdout of this program will be used as the top of the release notes for this release.
20+
cat << EOF
21+
## Using bzlmod with Bazel 6 or later:
22+
23+
Add to your \`MODULE.bazel\` file:
24+
25+
\`\`\`starlark
26+
bazel_dep(name = "stackb_ui_js", version = "${TAG}")
27+
\`\`\`
28+
EOF
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
# Reusable workflow that can be referenced by repositories in their `.github/workflows/release.yaml`.
2+
# See example usage in https://github.com/bazel-contrib/rules-template/blob/main/.github/workflows/release.yaml
3+
#
4+
# This workflow calls `.github/workflows/release_prep.sh` as the command to prepare the release.
5+
# Release notes are expected to be outputted to stdout from the release prep command.
6+
#
7+
# This workflow uses https://github.com/bazel-contrib/setup-bazel to prepare the cache folders.
8+
# Caching may be disabled by setting `mount_bazel_caches` to false.
9+
#
10+
# The workflow requires the following permissions to be set on the invoking job:
11+
#
12+
# permissions:
13+
# id-token: write # Needed to attest provenance
14+
# attestations: write # Needed to attest provenance
15+
# contents: write # Needed to upload release files
16+
17+
permissions: {}
18+
19+
on:
20+
# Make this workflow reusable, see
21+
# https://github.blog/2022-02-10-using-reusable-workflows-github-actions
22+
workflow_call:
23+
inputs:
24+
release_files:
25+
required: true
26+
description: |
27+
Newline-delimited globs of paths to assets to upload for release.
28+
relative to the module repository. The paths should include any files
29+
such as a release archive created by the release_prep script`.
30+
31+
See https://github.com/softprops/action-gh-release#inputs.
32+
type: string
33+
# TODO: there's a security design problem here:
34+
# Users of a workflow_dispatch trigger could fill in something via the GH Web UI
35+
# that would cause the release to use an arbitrary script.
36+
# That change wouldn't be reflected in the sources in the repo, and therefore
37+
# would not be verifiable by the attestation.
38+
# For now, we force this path to be hard-coded.
39+
#
40+
# release_prep_command:
41+
# default: .github/workflows/release_prep.sh
42+
# description: |
43+
# Command to run to prepare the release and generate release notes.
44+
# Release notes are expected to be outputted to stdout.
45+
# type: string
46+
bazel_test_command:
47+
default: "bazel build //..."
48+
description: |
49+
Bazel test command that may be overridden to set custom flags and targets.
50+
The --disk_cache=~/.cache/bazel-disk-cache --repository_cache=~/.cache/bazel-repository-cache flags are
51+
automatically appended to the command.
52+
type: string
53+
mount_bazel_caches:
54+
default: true
55+
description: |
56+
Whether to enable caching in the bazel-contrib/setup-bazel action.
57+
type: boolean
58+
prerelease:
59+
default: true
60+
description: Indicator of whether or not this is a prerelease.
61+
type: boolean
62+
draft:
63+
default: false
64+
description: |
65+
Whether the release should be created as a draft or published immediately.
66+
type: boolean
67+
tag_name:
68+
description: |
69+
The tag which is being released.
70+
By default, https://github.com/softprops/action-gh-release will use `github.ref_name`.
71+
type: string
72+
73+
jobs:
74+
build:
75+
outputs:
76+
release-files-artifact-id: ${{ steps.upload-release-files.outputs.artifact-id }}
77+
release-notes-artifact-id: ${{ steps.upload-release-notes.outputs.artifact-id }}
78+
runs-on: self-hosted
79+
steps:
80+
- name: Checkout
81+
uses: actions/checkout@v4
82+
with:
83+
ref: ${{ inputs.tag_name }}
84+
85+
- uses: bazel-contrib/setup-bazel@0.15.0
86+
with:
87+
disk-cache: ${{ inputs.mount_bazel_caches }}
88+
repository-cache: ${{ inputs.mount_bazel_caches }}
89+
90+
- name: Test
91+
run: ${{ inputs.bazel_test_command }} --disk_cache=~/.cache/bazel-disk-cache --repository_cache=~/.cache/bazel-repository-cache
92+
93+
# Fetch built artifacts (if any) from earlier jobs, which the release script may want to read.
94+
# Extract into ${GITHUB_WORKSPACE}/artifacts/*
95+
- uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
96+
97+
- name: Build release artifacts and prepare release notes
98+
run: |
99+
if [ ! -f ".github/workflows/release_prep.sh" ]; then
100+
echo "ERROR: create a .github/workflows/release_prep.sh script"
101+
exit 1
102+
fi
103+
.github/workflows/release_prep.sh ${{ inputs.tag_name || github.ref_name }} > release_notes.txt
104+
105+
- uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 #v4.6.0
106+
id: upload-release-files
107+
with:
108+
name: release_files
109+
path: ${{ inputs.release_files }}
110+
111+
- uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 #v4.6.0
112+
id: upload-release-notes
113+
with:
114+
name: release_notes
115+
path: release_notes.txt
116+
117+
attest:
118+
needs: build
119+
outputs:
120+
attestations-artifact-id: ${{ steps.upload-attestations.outputs.artifact-id }}
121+
permissions:
122+
id-token: write
123+
attestations: write
124+
runs-on: ubuntu-latest
125+
steps:
126+
# actions/download-artifact@v4 does not yet support downloading via the immutable artifact-id,
127+
# but the Javascript library does. See: https://github.com/actions/download-artifact/issues/349
128+
- run: npm install @actions/artifact@2.1.9
129+
- name: download-release-files
130+
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
131+
env:
132+
ARTIFACT_ID: ${{ needs.build.outputs.release-files-artifact-id }}
133+
with:
134+
script: |
135+
const {default: artifactClient} = require('@actions/artifact')
136+
const { ARTIFACT_ID } = process.env
137+
await artifactClient.downloadArtifact(ARTIFACT_ID, { path: 'release_files/'})
138+
139+
# https://github.com/actions/attest-build-provenance
140+
- name: Attest release files
141+
id: attest_release
142+
uses: actions/attest-build-provenance@v2
143+
with:
144+
subject-path: release_files/**/*
145+
146+
# The Bazel Central Registry requires an attestation per release archive, but the
147+
# actions/attest-build-provenance action only produces a single attestation for a
148+
# list of subjects. Copy the combined attestations into individually named
149+
# .intoto.jsonl files.
150+
- name: Write release archive attestations into intoto.jsonl
151+
id: write_release_archive_attestation
152+
run: |
153+
# https://bazel.build/rules/lib/repo/http#http_archive
154+
RELEASE_ARCHIVE_REGEX="(\.zip|\.jar|\.war|\.aar|\.tar|\.tar\.gz|\.tgz|\.tar\.xz|\.txz|\.tar\.xzt|\.tzst|\.tar\.bz2|\.ar|\.deb)$"
155+
156+
ATTESTATIONS_DIR=$(mktemp --directory)
157+
for filename in $(find release_files/ -type f -printf "%f\n"); do
158+
if [[ "${filename}" =~ $RELEASE_ARCHIVE_REGEX ]]; then
159+
ATTESTATION_FILE="$(basename "${filename}").intoto.jsonl"
160+
echo "Writing attestation to ${ATTESTATION_FILE}"
161+
cat ${{ steps.attest_release.outputs.bundle-path }} | jq --compact-output > "${ATTESTATIONS_DIR}/${ATTESTATION_FILE}"
162+
fi
163+
done
164+
echo "release_archive_attestations_dir=${ATTESTATIONS_DIR}" >> $GITHUB_OUTPUT
165+
- uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 #v4.6.0
166+
id: upload-attestations
167+
with:
168+
name: attestations
169+
path: ${{ steps.write_release_archive_attestation.outputs.release_archive_attestations_dir }}/*
170+
171+
release:
172+
needs: [build, attest]
173+
permissions:
174+
contents: write
175+
runs-on: ubuntu-latest
176+
steps:
177+
# actions/download-artifact@v4 does not yet support downloading via the immutable artifact-id,
178+
# but the Javascript library does. See: https://github.com/actions/download-artifact/issues/349
179+
- run: npm install @actions/artifact@2.1.9
180+
- name: download-artifacts
181+
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
182+
env:
183+
RELEASE_FILES_ARTIFACT_ID: ${{ needs.build.outputs.release-files-artifact-id }}
184+
RELEASE_NOTES_ARTIFACT_ID: ${{ needs.build.outputs.release-notes-artifact-id }}
185+
ATTESTATIONS_ARTIFACT_ID: ${{ needs.attest.outputs.attestations-artifact-id }}
186+
with:
187+
script: |
188+
const {default: artifactClient} = require('@actions/artifact')
189+
const { RELEASE_FILES_ARTIFACT_ID, RELEASE_NOTES_ARTIFACT_ID, ATTESTATIONS_ARTIFACT_ID } = process.env
190+
await Promise.all([
191+
artifactClient.downloadArtifact(RELEASE_FILES_ARTIFACT_ID, { path: 'release_files/'}),
192+
artifactClient.downloadArtifact(RELEASE_NOTES_ARTIFACT_ID, { path: 'release_notes/'}),
193+
artifactClient.downloadArtifact(ATTESTATIONS_ARTIFACT_ID, { path: 'attestations/'})
194+
])
195+
196+
- name: Release
197+
uses: softprops/action-gh-release@v2
198+
with:
199+
prerelease: ${{ inputs.prerelease }}
200+
draft: ${{ inputs.draft }}
201+
# Use GH feature to populate the changelog automatically
202+
generate_release_notes: true
203+
body_path: release_notes/release_notes.txt
204+
fail_on_unmatched_files: true
205+
tag_name: ${{ inputs.tag_name }}
206+
files: |
207+
release_files/**/*
208+
attestations/*

BUILD.bazel

Whitespace-only changes.

0 commit comments

Comments
 (0)