diff --git a/.bazelrc b/.bazelrc index 93ad7c8..f678853 100644 --- a/.bazelrc +++ b/.bazelrc @@ -20,3 +20,6 @@ build:noninteractive --show_timestamps build:noninteractive --announce_rc build:noninteractive --test_output=summary build:noninteractive --keep_going + +build:release --config=noninteractive +build:release --stamp diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..3fb73d9 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,23 @@ +name: "release" + +on: + workflow_dispatch: + inputs: + version: + type: string + description: Version of engflow_auth to release + required: true + +permissions: + contents: write + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: release + run: | + infra/release.sh "${{ github.events.inputs.version }}" + env: + GITHUB_TOKEN: ${{ github.token }} diff --git a/BUILD b/BUILD index b0bf57a..6d645fb 100644 --- a/BUILD +++ b/BUILD @@ -2,3 +2,12 @@ load("@gazelle//:def.bzl", "gazelle") # gazelle:prefix github.com/EngFlow/auth gazelle(name = "gazelle") + +filegroup( + name = "release_artifacts", + srcs = [ + "//cmd/engflow_auth:engflow_auth_linux_x64", + "//cmd/engflow_auth:engflow_auth_macos_arm64", + "//cmd/engflow_auth:engflow_auth_windows_x64", + ], +) diff --git a/cmd/engflow_auth/BUILD b/cmd/engflow_auth/BUILD index cad88f5..632a289 100644 --- a/cmd/engflow_auth/BUILD +++ b/cmd/engflow_auth/BUILD @@ -1,4 +1,5 @@ load("@rules_go//go:def.bzl", "go_binary", "go_cross_binary", "go_library", "go_test") +load("//infra:visibility.bzl", "RELEASE_ARTIFACT") go_library( name = "engflow_auth_lib", @@ -40,16 +41,19 @@ go_cross_binary( name = "engflow_auth_macos_arm64", platform = "@rules_go//go/toolchain:darwin_arm64_cgo", target = ":engflow_auth", + visibility = RELEASE_ARTIFACT, ) go_cross_binary( name = "engflow_auth_windows_x64", platform = "@rules_go//go/toolchain:windows_amd64_cgo", target = ":engflow_auth", + visibility = RELEASE_ARTIFACT, ) go_cross_binary( name = "engflow_auth_linux_x64", platform = "@rules_go//go/toolchain:linux_amd64_cgo", target = ":engflow_auth", + visibility = RELEASE_ARTIFACT, ) diff --git a/infra/BUILD b/infra/BUILD new file mode 100644 index 0000000..e69de29 diff --git a/infra/release.sh b/infra/release.sh new file mode 100755 index 0000000..0c84bd5 --- /dev/null +++ b/infra/release.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash + +set -o nounset -o pipefail -o errexit +[[ "${SCRIPT_DEBUG:-"off"}" == "on" ]] && set -o xtrace + +if [[ "$#" -ne 1 ]]; then + echo "Want 1 argument; got $# arguments" + exit 1 +fi + +readonly RELEASE_VERSION="$1" +readonly GH_CLI_URL='https://github.com/cli/cli/releases/download/v2.52.0/gh_2.52.0_linux_amd64.tar.gz' +readonly GH_CLI_EXPECTED_SHA256='3ea6ed8b2585f406a064cecd7e1501e58f56c8e7ca764ae1f3483d1b8ed68826' + +# Check that supplied version string follows semver +grep '[0-9]\+\.[0-9]\+\.[0-9]\+' <<<${RELEASE_VERSION} || { + echo "Supplied version string '${RELEASE_VERSION}' does not follow semver; exiting" + exit 1 +} + +function cleanup { + rm -rf "${GH_CLI_DIR}" +} + +# Download and verify Github CLI +# TODO(CUS-353): Remove this after installing Github CLI in the self-hosted +# environment (run via Docker?) +readonly GH_CLI_DIR="$(mktemp -d -t 'gh_cli_XXXXXXXX')" +curl --location "${GH_CLI_URL}" \ + | tee >(sha256sum - > "${GH_CLI_DIR}/archive_checksum.txt") \ + | tar \ + -C "${GH_CLI_DIR}" \ + --strip-components 1 \ + -xzvf \ + - +trap 'cleanup' EXIT +readonly GH_CLI="${GH_CLI_DIR}/bin/gh" +readonly GH_CLI_ACTUAL_SHA256="$(cat ${GH_CLI_DIR}/archive_checksum.txt | awk '{ print $1 }')" +if [[ "${GH_CLI_ACTUAL_SHA256}" != "${GH_CLI_EXPECTED_SHA256}" ]]; then + echo "SHA256 for Github CLI tarball ${GH_CLI_ACTUAL_SHA256} doesn't match expected value ${GH_CLI_ACTUAL_SHA256}; exiting" + exit 1 +fi + +# Check that the current commit is on either `main` or a release branch +readonly EXPECTED_RELEASE_BRANCH="$(sed 's|\([0-9]\+\.[0-9]\+\)\.[0-9]\+|release/v\1|' <<<${RELEASE_VERSION})" +git branch \ + --contains "$(git rev-parse HEAD)" \ + | grep "main|${EXPECTED_RELEASE_BRANCH}" \ + || { + echo "Commit $(git rev-parse HEAD) is not on main or release branch ${EXPECTED_RELEASE_BRANCH}; exiting" + exit 1 + } + +# Add a tag +git tag \ + --annotate \ + "v${RELEASE_VERSION}" \ + --message "Release v${RELEASE_VERSION}" +git push \ + --follow-tags +echo "Pushed new release tag: v${RELEASE_VERSION} at commit $(git rev-parse HEAD)" + +# Build release artifacts +bazel build \ + --config=release \ + -- \ + //:release_artifacts + +# Create release +${GH_CLI} release create \ + "v${RELEASE_VERSION}" \ + --generate-notes \ + "$(realpath bazel-out/k8-fastbuild-ST-*/bin/cmd/engflow_auth/engflow_auth_linux_x64)#engflow_auth (Linux, x64)" \ + "$(realpath bazel-out/k8-fastbuild-ST-*/bin/cmd/engflow_auth/engflow_auth_macos_arm64)#engflow_auth (macOS, arm64)" \ + "$(realpath bazel-out/k8-fastbuild-ST-*/bin/cmd/engflow_auth/engflow_auth_windows_x64)#engflow_auth (Windows, x64)" diff --git a/infra/visibility.bzl b/infra/visibility.bzl new file mode 100644 index 0000000..6d54a11 --- /dev/null +++ b/infra/visibility.bzl @@ -0,0 +1,5 @@ +"""Contains visibility constants to reduce duplication, increase BUILD file readability""" + +# Visibility used for artifacts that get released, which are defined by +# filegroup(s) in the top-level BUILD file. +RELEASE_ARTIFACT = ["//:__pkg__"]