Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
ci(bazel): Fixes an issue where bazel could not create runfiles on wi…
Browse files Browse the repository at this point in the history
…ndows.

This issue is due to som legacy runfiles linking where a manifest file was expected where it was not on windows.
  • Loading branch information
Lukas Holzer authored and lukasholzer committed Sep 25, 2020
1 parent b3987ab commit 88be25b
Show file tree
Hide file tree
Showing 17 changed files with 240 additions and 56 deletions.
8 changes: 7 additions & 1 deletion .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ build:debug --compilation_mode=dbg
# Turn off legacy external runfiles
# This prevents accidentally depending on this feature, which Bazel will remove.
build --nolegacy_external_runfiles
run --nolegacy_external_runfiles
test --nolegacy_external_runfiles

# Do not build runfile forests by default. If an execution strategy relies on runfile
# forests, the forest is created on-demand. See: https://github.com/bazelbuild/bazel/issues/6627
# and https://github.com/bazelbuild/bazel/commit/03246077f948f2790a83520e7dccc2625650e6df
build --nobuild_runfile_links


# Turn on --incompatible_strict_action_env which was on by default
Expand Down Expand Up @@ -116,7 +123,6 @@ test --spawn_strategy=local

build --experimental_inprocess_symlink_creation


# ------------------------------------------------------------------------------------------------
# Possible overrides
# ------------------------------------------------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ jobs:
# - static codeanalysis of the style files
bazel_stylelint:
executor: bazel
resource_class: large
resource_class: xlarge
steps:
- setup_bazel_ci
- run_bazel_stylelint
Expand All @@ -472,7 +472,7 @@ jobs:
# - build all targets with bazel
bazel_build:
executor: bazel
resource_class: large
resource_class: xlarge
steps:
- setup_bazel_ci
- run_bazel_build
Expand Down
9 changes: 6 additions & 3 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ http_archive(
url = "https://github.com/bazelbuild/rules_nodejs/releases/download/%s/rules_nodejs-%s.tar.gz" % (RULES_NODEJS_VERSION, RULES_NODEJS_VERSION),
patches = [
"//:rules_nodejs-npm-install+2.0.3.patch",
"//:rules_nodejs-launcher+2.0.3.patch",
]
)

Expand Down Expand Up @@ -54,21 +55,23 @@ npm_install(
data = [
"//:patches/@angular+bazel+10.0.6.patch",
"//:patches/@bazel+typescript+2.0.3.patch",
"//:patches/jest-haste-map+26.1.0.patch",
"//:patches/stylelint+13.2.1.patch",
"//:postinstall.js",
"//:view-engine-tsconfig.json"
],
package_json = "//:package.json",
package_lock_json = "//:package-lock.json",
quiet = False,
quiet = True,
symlink_node_modules = True,
)

# Install the @angular/bazel package into @npm_angular_bazel
# Note, this will probably break in a future rules_nodejs release.
# It causes all builds to fetch npm packages even if not needed (eg. only building go code)
load("@npm//:install_bazel_dependencies.bzl", "install_bazel_dependencies")
# load("@npm//:install_bazel_dependencies.bzl", "install_bazel_dependencies")

install_bazel_dependencies(suppress_warning = True)
# install_bazel_dependencies(suppress_warning = True)

# Setup the rules_sass toolchain
load("@io_bazel_rules_sass//sass:sass_repositories.bzl", "sass_repositories")
Expand Down
17 changes: 14 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"copy-generated-tokens": "node tools/shell-helpers/copy-folder.js $(bazelisk info bazel-genfiles)/libs/shared/design-tokens/build libs/shared/design-tokens/generated",
"bazel": "bazelisk",
"bazel:test": "bazelisk query \"attr(generator_function, jest, //...)\" | xargs bazelisk test",
"bazel:stylelint": "bazelisk query \"attr(generator_function, stylelint, //...)\" | xargs bazelisk test",
"bazel:stylelint": "node tools/scripts/stylelint.js",
"linting:test": "npx tslint --rules-dir dist/libs/components/tslint/src/rules --test libs/tools/linting/src/test/**/tslint.json"
},
"author": "Dynatrace",
Expand Down Expand Up @@ -173,6 +173,7 @@
"sass-graph": "^3.0.5",
"sass-loader": "^8.0.2",
"semver": "^7.3.2",
"shelljs": "^0.8.4",
"stylelint": "^13.2.1",
"stylelint-checkstyle-formatter": "^0.1.2",
"stylelint-config-prettier": "^8.0.2",
Expand Down
16 changes: 16 additions & 0 deletions patches/jest-haste-map+26.1.0.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
diff --git a/node_modules/jest-haste-map/build/crawlers/node.js b/node_modules/jest-haste-map/build/crawlers/node.js
index 6b6e11a..2ff08fa 100644
--- a/node_modules/jest-haste-map/build/crawlers/node.js
+++ b/node_modules/jest-haste-map/build/crawlers/node.js
@@ -205,7 +205,11 @@ function find(roots, extensions, ignore, callback) {

function findNative(roots, extensions, ignore, callback) {
const args = Array.from(roots);
+ args.push('(');
args.push('-type', 'f');
+ args.push('-o');
+ args.push('-type', 'l');
+ args.push(')');

if (extensions.length) {
args.push('(');
16 changes: 16 additions & 0 deletions patches/stylelint+13.2.1.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
diff --git a/node_modules/stylelint/lib/standalone.js b/node_modules/stylelint/lib/standalone.js
index 630af7e..dbf55e7 100644
--- a/node_modules/stylelint/lib/standalone.js
+++ b/node_modules/stylelint/lib/standalone.js
@@ -198,9 +198,9 @@ module.exports = function(options) {
fileCache = new FileCache(cacheLocation);
// Remove cache file if cache option is disabled
fileCache.destroy();
- }
+ }

- return globby(fileList, globbyOptions)
+ return Promise.resolve(fileList)
.then((filePaths) => {
// The ignorer filter needs to check paths relative to cwd
filePaths = filterFilePaths(
10 changes: 6 additions & 4 deletions postinstall.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ const { writeFileSync, readFileSync } = require('fs');

const MAIN_FIELD_NAME = 'main';
const NGCC_MAIN_FIELD_NAME = 'main_ivy_ngcc';
const NGCC_BINARY = resolve('./node_modules/.bin/ngcc');
const NGC_BINARY = resolve('./node_modules/.bin/ngc');
const NGCC_BINARY = resolve(
'./node_modules/@angular/compiler-cli/ngcc/main-ngcc.js',
);
const NGC_BINARY = resolve('./node_modules/@angular/compiler-cli/src/main.js');

async function main() {
// Applying all the patches to the packages
Expand All @@ -20,10 +22,10 @@ async function main() {

// Generate Angular ngfactory.js, ngsummary.js files for the dependencies,
// that are needed for ViewEngine
await execCommand(`${NGC_BINARY} -p view-engine-tsconfig.json`);
await execCommand(`node ${NGC_BINARY} -p view-engine-tsconfig.json`);
// Generate Ivy entry points
await execCommand(
`${NGCC_BINARY} --properties es2015 browser module main --first-only --create-ivy-entry-points`,
`node ${NGCC_BINARY} --properties es2015 browser module main --first-only --create-ivy-entry-points`,
);
// link the ivy entry points
updateNgccMainFields();
Expand Down
23 changes: 23 additions & 0 deletions rules_nodejs-launcher+2.0.3.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
diff --git internal/node/launcher.sh internal/node/launcher.sh
index e685da73..ba38076e 100644
--- internal/node/launcher.sh
+++ internal/node/launcher.sh
@@ -148,14 +148,16 @@ fi

# Export the location of the runfiles helpers script
export BAZEL_NODE_RUNFILES_HELPER=$(rlocation "TEMPLATED_runfiles_helper_script")
-if [[ "${BAZEL_NODE_RUNFILES_HELPER}" != /* ]] && [[ ! "${BAZEL_NODE_RUNFILES_HELPER}" =~ ^[A-Z]:[\\/] ]]; then
+# Paths can be with lower and upper case on windows because of the msys64 package in the powershell
+if [[ "${BAZEL_NODE_RUNFILES_HELPER}" != /* ]] && [[ ! "${BAZEL_NODE_RUNFILES_HELPER}" =~ ^[A-Za-z]:[\/\\] ]]; then
export BAZEL_NODE_RUNFILES_HELPER=$(pwd)/${BAZEL_NODE_RUNFILES_HELPER}
fi

# Export the location of the require patch script as it can be used to bootstrap
# node require patch if needed
export BAZEL_NODE_PATCH_REQUIRE=$(rlocation "TEMPLATED_require_patch_script")
-if [[ "${BAZEL_NODE_PATCH_REQUIRE}" != /* ]] && [[ ! "${BAZEL_NODE_PATCH_REQUIRE}" =~ ^[A-Z]:[\\/] ]]; then
+# Paths can be with lower and upper case on windows because of the msys64 package in the powershell
+if [[ "${BAZEL_NODE_PATCH_REQUIRE}" != /* ]] && [[ ! "${BAZEL_NODE_PATCH_REQUIRE}" =~ ^[A-Za-z]:[\/\\] ]]; then
export BAZEL_NODE_PATCH_REQUIRE=$(pwd)/${BAZEL_NODE_PATCH_REQUIRE}
fi

9 changes: 7 additions & 2 deletions tools/bazel_rules/jest/jest-resolver.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
const { sync } = require('resolve');
const { readFileSync, existsSync, lstatSync } = require('fs');
const { resolve } = require('path');
const { resolve, join } = require('path');

// Get the module mappings out of the module mappings file from bazel
const moduleMappingFile = process.env.BAZEL_TEST_MODULE_MAPPING;
const [bazelPackage, bazelTarget] = process.env.BAZEL_TARGET.split(':');
const moduleMappingFile = join(
bazelPackage.replace('//', ''),
`_${bazelTarget}.module_mappings.json`,
);

// bazel run files helper used to resolve paths that are created with `$(location ...)`
const runFilesHelper = require(`${process.env.BAZEL_NODE_RUNFILES_HELPER}`);

Expand Down
50 changes: 25 additions & 25 deletions tools/bazel_rules/jest/jest-runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ const { argv } = require('yargs');

// Path of the test.sh binary that gets created from the nodejs_test
const { TEST_BINARY } = process.env;
// Bazels node runfiles helper
const RUNFILES_HELPER = require(process.env.BAZEL_NODE_RUNFILES_HELPER);

/**
* Updates the jest config json with additional properties
Expand Down Expand Up @@ -48,35 +50,33 @@ function updateJestConfig(suiteName, config = undefined) {
async function main() {
const { jestConfig, setupFile, files, suite } = argv;
const jestConfigPath = updateJestConfig(suite, jestConfig);
const base = dirname(jestConfigPath);

process.env.BAZEL_TEST_MODULE_MAPPING = join(
dirname(TEST_BINARY),
`_${suite}.module_mappings.json`,
);

const resolvedFiles = files
.split(',')
.map((source) => join(base, source).replace(/ts$/, 'js'));

const cliArgs = {
/**
* This is a hack to avoid using the jest-haste-map fs that does not support symbolic links
* https://github.com/facebook/metro/issues/1#issuecomment-641633646
*/
_: resolvedFiles,
runTestsByPath: true,
verbose: true,
resolver: resolve('tools/bazel_rules/jest/jest-resolver.js'),
rootDir: resolve('./'),
colors: false,
};
.map((source) =>
join(RUNFILES_HELPER.package, source).replace(/ts$/, 'js'),
);

if (setupFile) {
cliArgs.setupFilesAfterEnv = [resolve(setupFile).replace(/ts$/, 'js')];
}

const { results } = await runCLI(cliArgs, [jestConfigPath]);
const { results } = await runCLI(
{
/**
* This is a hack to avoid using the jest-haste-map fs that does not support symbolic links
* https://github.com/facebook/metro/issues/1#issuecomment-641633646
*/
_: resolvedFiles,
setupFilesAfterEnv: setupFile
? [resolve(setupFile).replace(/ts$/, 'js')]
: [],
runTestsByPath: true,
verbose: true,
expand: true,
cache: false,
resolver: resolve('tools/bazel_rules/jest/jest-resolver.js'),
rootDir: resolve('./'),
colors: true,
},
[jestConfigPath],
);

if (!results.success) {
throw new Error(`Failed executing jest tests`);
Expand Down
7 changes: 2 additions & 5 deletions tools/bazel_rules/stylelint/junit-formatter/parse-suite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,12 @@
*/

import { LintResult, Warning } from 'stylelint';
import { relative, join } from 'path';
import { relative } from 'path';
import { ParsedSuite, ParsedCase } from './parsed-suite.interface';

// bazel run files helper used to resolve paths that are created with `$(location ...)`
const { dir, workspace } = require(`${process.env.BAZEL_NODE_RUNFILES_HELPER}`);

/** Creates an object that can be used to create an XML out of the provided lint result */
export function parseSuite(testSuite: LintResult): ParsedSuite {
const name = relative(join(dir, workspace), testSuite.source);
const name = relative(process.cwd(), testSuite.source);
const failuresCount = testSuite.warnings.length;
const testCases = testSuite.errored
? testSuite.warnings.map((testCase: Warning) =>
Expand Down
27 changes: 19 additions & 8 deletions tools/bazel_rules/stylelint/run-stylelint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,15 @@
import { lint, LinterResult } from 'stylelint';
import { junitFormatter, createXML } from './junit-formatter';
import { writeFileSync } from 'fs';
import { resolve, relative } from 'path';
import { options } from 'yargs';

const { BAZEL_NODE_RUNFILES_HELPER, XML_OUTPUT_FILE } = process.env;
const { XML_OUTPUT_FILE } = process.env;

if (!BAZEL_NODE_RUNFILES_HELPER || !XML_OUTPUT_FILE) {
if (!XML_OUTPUT_FILE) {
throw new Error('Bazel environment variables are not set!');
}

// bazel run files helper used to resolve paths that are created with `$(location ...)`
const runFilesHelper = require(BAZEL_NODE_RUNFILES_HELPER);

const { files, allowEmpty, config } = options({
files: { type: 'array', default: [] },
config: { type: 'string', demandOption: true },
Expand All @@ -44,16 +42,29 @@ async function main(): Promise<void> {
};
} else {
lintingOutcome = await lint({
configFile: runFilesHelper.resolve(config),
files: files.map((f) => runFilesHelper.resolve(f)),
configFile: resolve(config),
files: files.map((f) => resolve(f)),
disableDefaultIgnores: true,
formatter: junitFormatter,
});
}

writeFileSync(XML_OUTPUT_FILE as string, lintingOutcome.output);

const lintResult = lintingOutcome.results.map((suite) => {
const file = relative(process.cwd(), suite.source);
const warnings = suite.warnings.map((c) => `L${c.line}: ${c.text}`);
const icon = suite.errored ? '\u2705' : '\u274C';

return `
${icon} ${file} ${warnings.length ? '\n\n' + warnings.join('\n') : ''}`;
});

if (lintingOutcome.errored) {
throw new Error('Lint errors found in the listed files.');
throw new Error(`Lint errors found in the listed files:
${lintResult}
`);
}
}

Expand Down
4 changes: 2 additions & 2 deletions tools/bazel_rules/stylelint/stylelint_macro.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ def stylelint_macro(
**kwargs: remaining args to pass to the stylelint_test rule
"""

args = ["--files=\"$(location %s)\"" % s for s in srcs]
args = ["--files=\"$(rootpath %s)\"" % s for s in srcs]

if config:
srcs.append(config)
else:
config = "//:.stylelintrc"

# append the config file
args.append("--config $(location %s)" % config)
args.append("--config $(rootpath %s)" % config)

# # If no tests are matching the glob the process wont exit if set
if allow_empty_input:
Expand Down
5 changes: 5 additions & 0 deletions tools/scripts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# What is the purpose of those scripts

This folder contains scripts to execute commands platform independently. As
node.js is working on Windows, Linux and macOs it is better than having shell
scripts for each language. This should simplify invoking bazel commands.
Loading

0 comments on commit 88be25b

Please sign in to comment.