Skip to content

Commit

Permalink
feat(circleci-orb): command for setting up remote bazel execution (#839)
Browse files Browse the repository at this point in the history
* feat(circleci-orb): command for setting up remote bazel execution

* build: use remote execution setup command from orb
  • Loading branch information
devversion authored Sep 23, 2022
1 parent 16a0ad3 commit 989b9f5
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 8 deletions.
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/[email protected]
win: circleci/[email protected]
devinfra: angular/[email protected].1
devinfra: angular/[email protected].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;
});

0 comments on commit 989b9f5

Please sign in to comment.