Skip to content

feat(circleci-orb): command for setting up remote bazel execution #839

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ version: 2.1
orbs:
buildalert: oss-tools/buildalert@0.1.0
win: circleci/windows@2.2.0
devinfra: angular/dev-infra@1.0.1
devinfra: angular/dev-infra@1.0.5

# **Note**: When updating the beginning of the cache key, also update the cache key to match
# the new cache key prefix. This allows us to take advantage of CircleCI's fallback caching.
Expand All @@ -16,8 +16,6 @@ var_1: &cache_key v2-{{arch}}-{{ checksum ".bazelversion" }}-{{ checksum "WORKSP
# versions and ultimately cause the cache restoring to be slower.
var_2: &cache_fallback_key v2-{{arch}}-{{ checksum ".bazelversion" }}-

var_3: &gcp_decrypt_token 'angular'

var_4: &restore_cache
restore_cache:
keys:
Expand All @@ -37,8 +35,6 @@ var_6: &default_executor_settings
resource_class:
type: string
default: medium
environment:
GCP_DECRYPT_TOKEN: *gcp_decrypt_token
resource_class: << parameters.resource_class >>
working_directory: ~/ng

Expand Down Expand Up @@ -84,7 +80,7 @@ commands:
description: 'Setting up Bazel configuration for CI'
steps:
- run: echo "import %workspace%/.circleci/linux-bazel.rc" >> ./.bazelrc
- run: ./.circleci/setup-bazel.sh
- devinfra/setup-bazel-remote-exec

prepare_and_store_test_results:
description: 'Prepare and upload test results'
Expand Down
Binary file removed .circleci/gcp_token
Binary file not shown.
4 changes: 2 additions & 2 deletions circleci-orb/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary")

ORB_NAME = "angular/dev-infra"

ORB_VERSION = "1.0.3"
ORB_VERSION = "1.0.5"

nodejs_binary(
name = "pack_orb_script",
Expand All @@ -17,6 +16,7 @@ filegroup(
name = "orb_generated_files",
srcs = [
"//circleci-orb/scripts/rebase-pr-on-target-branch:script",
"//circleci-orb/scripts/setup-bazel-remote-exec:script",
],
)

Expand Down
24 changes: 24 additions & 0 deletions circleci-orb/commands/setup-bazel-remote-exec.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
description: Setup Bazel remote execution

parameters:
bazelrc:
type: string
default: ''
description: |
If specified, the given `bazelrc` file is being updated to always run
with the `--config=remote` flag.
shell:
type: string
default: ''
description: |
Shell to use for executing the command. Useful for Windows where a
non-bash shell is the default.

steps:
- run:
environment:
BAZELRC_PATH: << parameters.bazelrc >>
NGAT: 'HlA2BJMJAXPDI1UAn5gytw=='
name: Setting up Bazel remote execution
shell: << parameters.shell >>
command: << include(../dist/bin/circleci-orb/scripts/setup-bazel-remote-exec/script.sh) >>
47 changes: 47 additions & 0 deletions circleci-orb/scripts/setup-bazel-remote-exec/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
load("@build_bazel_rules_nodejs//:index.bzl", "copy_to_bin", "nodejs_binary")
load("//tools:defaults.bzl", "esbuild", "ts_library")
load("//circleci-orb:index.bzl", "nodejs_script_to_sh_script")

package(default_visibility = ["//circleci-orb:__subpackages__"])

copy_to_bin(
name = "gcp_token",
srcs = ["gcp_token.data"],
)

ts_library(
name = "setup-bazel-remote-exec",
srcs = glob(["*.ts"]),
# TODO(devversion): Remove this when `ts_library` supports `.mts` extension.
devmode_module = "commonjs",
deps = [
"@npm//@types/node",
],
)

nodejs_binary(
name = "encrypt",
data = [":setup-bazel-remote-exec"],
entry_point = ":encrypt.ts",
)

esbuild(
name = "bundle",
srcs = [":gcp_token"],
args = {
"loader": {
".data": "binary",
},
},
entry_point = "index.ts",
format = "iife",
minify = True,
sourcemap = "",
deps = [":setup-bazel-remote-exec"],
)

nodejs_script_to_sh_script(
name = "script",
bundle_file = ":bundle.js",
output_file = "script.sh",
)
12 changes: 12 additions & 0 deletions circleci-orb/scripts/setup-bazel-remote-exec/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

export const alg = 'aes-256-gcm';
export const at = process.env.NGAT!;
export const k = process.env.CIRCLE_PROJECT_USERNAME!.padEnd(32, '<');
export const iv = '000003213213123213';
20 changes: 20 additions & 0 deletions circleci-orb/scripts/setup-bazel-remote-exec/encrypt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {createCipheriv} from 'crypto';
import {k, iv, alg} from './constants';
import fs from 'fs';

const [inputPath, outputPath] = process.argv.slice(2);
const input = fs.readFileSync(inputPath, 'utf8');
const cip = createCipheriv(alg, k, iv);
const enc = cip.update(input, 'utf8', 'binary') + cip.final('binary');

fs.writeFileSync(outputPath, enc, 'binary');

console.info('Auth tag:', cip.getAuthTag().toString('base64'));
Binary file not shown.
40 changes: 40 additions & 0 deletions circleci-orb/scripts/setup-bazel-remote-exec/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

// @ts-ignore
import tokenRaw from './gcp_token.data';
import {k, iv, alg, at} from './constants';
import {createDecipheriv} from 'crypto';
import path from 'path';
import fs from 'fs';
import os from 'os';

async function main(bazelRcPath: string | undefined) {
const t: Uint8Array = tokenRaw;
const dcip = createDecipheriv(alg, k, iv).setAuthTag(Buffer.from(at, 'base64'));
const dec = dcip.update(t, undefined, 'utf8') + dcip.final('utf8');

const destPath =
os.platform() === 'win32'
? path.join(process.env.APPDATA!, 'gcloud/application_default_credentials.json')
: path.join(process.env.HOME!, '.config/gcloud/application_default_credentials.json');

await fs.promises.mkdir(path.dirname(destPath), {recursive: true});
await fs.promises.writeFile(destPath, dec, 'utf8');

if (bazelRcPath) {
let content = await fs.promises.readFile(bazelRcPath, 'utf8');
content += '\nbuild --config=remote';
await fs.promises.writeFile(bazelRcPath, 'utf8');
}
}

main(process.env.BAZELRC_PATH).catch((e) => {
console.error(e);
process.exitCode = 1;
});