diff --git a/README.md b/README.md index e7018e06046800d19f2f989db482e201b8d4497f..2f352b941f49afa4944116da7faae114812401b3 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ More precisely, it can be used by all projects based on [npm](https://www.npmjs. ## Usage -This template can be used both as a [CI/CD component](https://docs.gitlab.com/ee/ci/components/#use-a-component) +This template can be used both as a [CI/CD component](https://docs.gitlab.com/ee/ci/components/#use-a-component) or using the legacy [`include:project`](https://docs.gitlab.com/ee/ci/yaml/index.html#includeproject) syntax. ### Use as a CI/CD component @@ -30,9 +30,9 @@ Add the following to your `.gitlab-ci.yml`: ```yaml include: # 1: include the template - - project: 'to-be-continuous/node' - ref: '4.0.0' - file: '/templates/gitlab-ci-node.yml' + - project: "to-be-continuous/node" + ref: "4.0.0" + file: "/templates/gitlab-ci-node.yml" variables: # 2: set/override template variables @@ -44,15 +44,15 @@ variables: The Node.js template uses some global configuration used throughout all jobs. -| Input / Variable | Description | Default value | -|------------------------|--------------------------------------------------------------------------------------------------|-------------------| -| `image` / `NODE_IMAGE` | The Docker image used to run Node.js <br/>:warning: **set the version required by your project** | `registry.hub.docker.com/library/node:lts-alpine` | -| `manager` / `NODE_MANAGER` | The package manager used by your project (one of `npm`, `yarn` or `pnpm`)<br/>**If undefined, automatic detection** | _none_ (auto) | -| `config-registry` / `NODE_CONFIG_REGISTRY` | Main npm [registry](https://docs.npmjs.com/cli/v8/using-npm/registry) to use | _none_ | -| `config-scoped-registries` / `NODE_CONFIG_SCOPED_REGISTRIES` | Space separated list of npm [scoped registries](https://docs.npmjs.com/cli/v8/using-npm/scope#associating-a-scope-with-a-registry) (formatted as `@somescope:https://some.npm.registry/some/repo @anotherscope:https://another.npm.registry/another/repo`) | _none_ | -| `project-dir` / `NODE_PROJECT_DIR` | Node project root directory | `.` | -| `source-dir` / `NODE_SOURCE_DIR` | Sources directory | `src` | -| `install-extra-opts` / `NODE_INSTALL_EXTRA_OPTS` | Extra options to install project dependencies (either [`npm ci`](https://docs.npmjs.com/cli/ci.html/), [`yarn install`](https://yarnpkg.com/cli/install) or [`pnpm install`](https://pnpm.io/cli/install)) | _none_ | +| Input / Variable | Description | Default value | +| ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | +| `image` / `NODE_IMAGE` | The Docker image used to run Node.js <br/>:warning: **set the version required by your project** | `registry.hub.docker.com/library/node:lts-alpine` | +| `manager` / `NODE_MANAGER` | The package manager used by your project (one of `npm`, `yarn` or `pnpm`)<br/>**If undefined, automatic detection** | _none_ (auto) | +| `config-registry` / `NODE_CONFIG_REGISTRY` | Main npm [registry](https://docs.npmjs.com/cli/v8/using-npm/registry) to use | _none_ | +| `config-scoped-registries` / `NODE_CONFIG_SCOPED_REGISTRIES` | Space separated list of npm [scoped registries](https://docs.npmjs.com/cli/v8/using-npm/scope#associating-a-scope-with-a-registry) (formatted as `@somescope:https://some.npm.registry/some/repo @anotherscope:https://another.npm.registry/another/repo`) | _none_ | +| `project-dir` / `NODE_PROJECT_DIR` | Node project root directory | `.` | +| `source-dir` / `NODE_SOURCE_DIR` | Sources directory | `src` | +| `install-extra-opts` / `NODE_INSTALL_EXTRA_OPTS` | Extra options to install project dependencies (either [`npm ci`](https://docs.npmjs.com/cli/ci.html/), [`yarn install`](https://yarnpkg.com/cli/install) or [`pnpm install`](https://pnpm.io/cli/install)) | _none_ | ### Using scoped registries @@ -60,9 +60,9 @@ Scoped registries allow to pull and publish packages using multiple registries. Examples: -* `npm install foo` installs `foo` package from https://www.npmjs.com/ by default, -* `npm install @angular/core` installs `@angular/core` package from https://www.npmjs.com/ if no npm registry associated to scope `@angular` is declared, -* `npm install @acme-corp/bar` installs `@acme-corp/bar` package from https://registry.acme.corp/npm if this registry url is associated to scope `@acme-corp`. +- `npm install foo` installs `foo` package from https://www.npmjs.com/ by default, +- `npm install @angular/core` installs `@angular/core` package from https://www.npmjs.com/ if no npm registry associated to scope `@angular` is declared, +- `npm install @acme-corp/bar` installs `@acme-corp/bar` package from https://registry.acme.corp/npm if this registry url is associated to scope `@acme-corp`. First of all, be aware that the Node.js template automatically configures the [GitLab's project-level npm packages registry](https://docs.gitlab.com/ee/user/packages/npm_registry/) associated to a scope corresponding to the root of the project (ex: project `https://gitlab.example.com/my-org/engineering-group/team-amazing/analytics` will have GitLab's project-level npm packages registry scope `@my-org`). Therefore, GitLab's project-level npm packages registry can freely be used both to install packages (with the right scope) or even to [publish](#node-publish-job) your own packages. @@ -70,16 +70,15 @@ Therefore, GitLab's project-level npm packages registry can freely be used both You may configure additional [scoped registries](https://docs.npmjs.com/cli/v8/using-npm/scope#associating-a-scope-with-a-registry) with the `$NODE_CONFIG_SCOPED_REGISTRIES` variable. The value is expected as a (whitespace-separated) list of `@registry-scope:registry-url`. -The Node.js template also supports authentication for each, simply by defining the appropriate variable (as project or group secret variables) +The Node.js template also supports authentication for each, simply by defining the appropriate variable (as project or group secret variables) depending on the desired authentication method: -* `NODE_REGISTRY_<SCOPE>_AUTH_TOKEN`: authentication token -* `NODE_REGISTRY_<SCOPE>_AUTH_BASIC`: base64 authentication string (`base64(username + ':' + password)`) - +- `NODE_REGISTRY_<SCOPE>_AUTH_TOKEN`: authentication token +- `NODE_REGISTRY_<SCOPE>_AUTH_BASIC`: base64 authentication string (`base64(username + ':' + password)`) :warning: The `<SCOPE>` part is the `registry-scope` transformed in [SCREAMING_SNAKE_CASE](https://en.wikipedia.org/wiki/Snake_case) (uppercase words separated by underscores). -Example: +Example: ```yml variables: @@ -95,10 +94,10 @@ The Node template features a job `node-lint` that performs Node.js source code * It is bound to the `build` stage, and uses the following variable: -| Input / Variable | Description | Default value | -|--------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------| -| `lint-enabled` / `NODE_LINT_ENABLED` | Set to `true` to enable lint analysis | _none_ (disabled) | -| `lint-args` / `NODE_LINT_ARGS` | npm [run script](https://docs.npmjs.com/cli/v8/commands/npm-run-script) arguments to execute the lint analysis <br/> yarn [run script](https://classic.yarnpkg.com/en/docs/cli/run) arguments to execute the lint analysis <br/> pnpm [run script](https://pnpm.io/cli/run) arguments to execute the lint analysis| `run lint` | +| Input / Variable | Description | Default value | +| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------- | +| `lint-enabled` / `NODE_LINT_ENABLED` | Set to `true` to enable lint analysis | _none_ (disabled) | +| `lint-args` / `NODE_LINT_ARGS` | npm [run script](https://docs.npmjs.com/cli/v8/commands/npm-run-script) arguments to execute the lint analysis <br/> yarn [run script](https://classic.yarnpkg.com/en/docs/cli/run) arguments to execute the lint analysis <br/> pnpm [run script](https://pnpm.io/cli/run) arguments to execute the lint analysis | `run lint` | The job generates a lint report that you will find here: `NODE_PROJECT_DIR/reports/node-lint.xslint.json`. @@ -111,13 +110,12 @@ for jobs dependency reasons (some jobs such as SONAR analysis have a dependency This job is bound to the `build` stage, and uses the following variables: -| Input / Variable | Description | Default value | -|-------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------| -| `build-disabled` / `NODE_BUILD_DISABLED` | Set to `true` to disable build | _none_ (enabled) | -| `build-dir` / `NODE_BUILD_DIR` | Variable to define build directory | `dist` | -| `build-args` / `NODE_BUILD_ARGS` | npm [run script](https://docs.npmjs.com/cli/v8/commands/npm-run-script) arguments <br/> yarn [run script](https://classic.yarnpkg.com/en/docs/cli/run) arguments <br/> pnpm [run script](https://pnpm.io/cli/run) arguments <br/>⚠ default value should be overridden for `pnpm` as `--prod` is not a valid option. | `run build --prod` | -| `test-args` / `NODE_TEST_ARGS` | npm [test](https://docs.npmjs.com/cli/v8/commands/npm-test) arguments <br/> yarn [test](https://classic.yarnpkg.com/en/docs/cli/test) arguments <br/> pnpm [test](https://pnpm.io/cli/test) arguments | `test -- --coverage` | - +| Input / Variable | Description | Default value | +| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | +| `build-disabled` / `NODE_BUILD_DISABLED` | Set to `true` to disable build | _none_ (enabled) | +| `build-dir` / `NODE_BUILD_DIR` | Variable to define build directory | `dist` | +| `build-args` / `NODE_BUILD_ARGS` | npm [run script](https://docs.npmjs.com/cli/v8/commands/npm-run-script) arguments <br/> yarn [run script](https://classic.yarnpkg.com/en/docs/cli/run) arguments <br/> pnpm [run script](https://pnpm.io/cli/run) arguments <br/>⚠ default value should be overridden for `pnpm` as `--prod` is not a valid option. | `run build --prod` | +| `test-args` / `NODE_TEST_ARGS` | npm [test](https://docs.npmjs.com/cli/v8/commands/npm-test) arguments <br/> yarn [test](https://classic.yarnpkg.com/en/docs/cli/test) arguments <br/> pnpm [test](https://pnpm.io/cli/test) arguments | `test -- --coverage` | #### Unit Tests and Code Coverage reports @@ -130,13 +128,13 @@ Additionally, if also using SonarQube, you'll have to enable some extra reporter Here is the required configuration if you're using [Jest](https://jestjs.io/) as unit testing framework. -| Reporter | Needs `npm install` | Expected report file | Usage | -| ---------------- | --------------------- | ----------------- | ----------------- | -| [jest-junit](https://github.com/jest-community/jest-junit) | Yes | `reports/node-test.xunit.xml` | [GitLab unit tests integration](https://docs.gitlab.com/ee/ci/testing/unit_test_reports.html) _(JUnit format)_ | -| istanbul [text](https://istanbul.js.org/docs/advanced/alternative-reporters/#text) | No | N/A _(stdout)_ | [GitLab MR test coverage results](https://docs.gitlab.com/ee/ci/pipelines/settings.html#merge-request-test-coverage-results) _(GitLab grabs coverage from stdout)_ | -| istanbul [cobertura](https://istanbul.js.org/docs/advanced/alternative-reporters/#cobertura) | No | `reports/cobertura-coverage.xml` | [GitLab code coverage integration](https://docs.gitlab.com/ee/ci/testing/test_coverage_visualization.html) _(Cobertura format)_ | -| [jest-sonar](https://github.com/sh33dafi/jest-sonar) | Yes | `reports/node-test.sonar.xml` | [SonarQube unit tests integration](https://docs.sonarqube.org/latest/analysis/generic-test/) _(generic SonarQube format)_ | -| istanbul [lcovonly](https://istanbul.js.org/docs/advanced/alternative-reporters/#lcovonly) | No | `reports/lcov.info` | [SonarQube code coverage integration](https://docs.sonarqube.org/latest/analysis/test-coverage/javascript-typescript-test-coverage/) _(JS/TS LCOV format)_ | +| Reporter | Needs `npm install` | Expected report file | Usage | +| -------------------------------------------------------------------------------------------- | ------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| [jest-junit](https://github.com/jest-community/jest-junit) | Yes | `reports/node-test.xunit.xml` | [GitLab unit tests integration](https://docs.gitlab.com/ee/ci/testing/unit_test_reports.html) _(JUnit format)_ | +| istanbul [text](https://istanbul.js.org/docs/advanced/alternative-reporters/#text) | No | N/A _(stdout)_ | [GitLab MR test coverage results](https://docs.gitlab.com/ee/ci/pipelines/settings.html#merge-request-test-coverage-results) _(GitLab grabs coverage from stdout)_ | +| istanbul [cobertura](https://istanbul.js.org/docs/advanced/alternative-reporters/#cobertura) | No | `reports/cobertura-coverage.xml` | [GitLab code coverage integration](https://docs.gitlab.com/ee/ci/testing/test_coverage_visualization.html) _(Cobertura format)_ | +| [jest-sonar](https://github.com/sh33dafi/jest-sonar) | Yes | `reports/node-test.sonar.xml` | [SonarQube unit tests integration](https://docs.sonarqube.org/latest/analysis/generic-test/) _(generic SonarQube format)_ | +| istanbul [lcovonly](https://istanbul.js.org/docs/advanced/alternative-reporters/#lcovonly) | No | `reports/lcov.info` | [SonarQube code coverage integration](https://docs.sonarqube.org/latest/analysis/test-coverage/javascript-typescript-test-coverage/) _(JS/TS LCOV format)_ | Here is an example of a `jest.config.js` configuration file with all the above reporters configured as expected: @@ -177,24 +175,26 @@ Here is an example of a `jest.config.js` configuration file with all the above r Here is the required configuration if you're using [Mocha](https://mochajs.org/) as unit testing framework. -| Reporter | Needs `npm install` | Expected report file | Usage | -| ---------------- | --------------------- | ----------------- | ----------------- | -| [mocha-junit-reporter](https://github.com/michaelleeallen/mocha-junit-reporter) | Yes | `reports/node-test.xunit.xml` | [GitLab unit tests integration](https://docs.gitlab.com/ee/ci/testing/unit_test_reports.html) _(JUnit format)_ | -| istanbul [text](https://istanbul.js.org/docs/advanced/alternative-reporters/#text) | Yes (in `nyc` package) | N/A _(stdout)_ | [GitLab MR test coverage results](https://docs.gitlab.com/ee/ci/pipelines/settings.html#merge-request-test-coverage-results) _(GitLab grabs coverage from stdout)_ | -| istanbul [cobertura](https://istanbul.js.org/docs/advanced/alternative-reporters/#cobertura) | Yes (in `nyc` package) | `reports/cobertura-coverage.xml` | [GitLab code coverage integration](https://docs.gitlab.com/ee/ci/testing/test_coverage_visualization.html) _(Cobertura format)_ | -| [mocha-sonarqube-reporter](https://github.com/mmouterde/mocha-sonarqube-reporter) | Yes | `reports/node-test.sonar.xml` | [SonarQube unit tests integration](https://docs.sonarqube.org/latest/analysis/generic-test/) _(generic SonarQube format)_ | -| istanbul [lcovonly](https://istanbul.js.org/docs/advanced/alternative-reporters/#lcovonly) | Yes (in `nyc` package) | `reports/lcov.info` | [SonarQube code coverage integration](https://docs.sonarqube.org/latest/analysis/test-coverage/javascript-typescript-test-coverage/) _(JS/TS LCOV format)_ | +| Reporter | Needs `npm install` | Expected report file | Usage | +| -------------------------------------------------------------------------------------------- | ---------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| [mocha-junit-reporter](https://github.com/michaelleeallen/mocha-junit-reporter) | Yes | `reports/node-test.xunit.xml` | [GitLab unit tests integration](https://docs.gitlab.com/ee/ci/testing/unit_test_reports.html) _(JUnit format)_ | +| istanbul [text](https://istanbul.js.org/docs/advanced/alternative-reporters/#text) | Yes (in `nyc` package) | N/A _(stdout)_ | [GitLab MR test coverage results](https://docs.gitlab.com/ee/ci/pipelines/settings.html#merge-request-test-coverage-results) _(GitLab grabs coverage from stdout)_ | +| istanbul [cobertura](https://istanbul.js.org/docs/advanced/alternative-reporters/#cobertura) | Yes (in `nyc` package) | `reports/cobertura-coverage.xml` | [GitLab code coverage integration](https://docs.gitlab.com/ee/ci/testing/test_coverage_visualization.html) _(Cobertura format)_ | +| [mocha-sonarqube-reporter](https://github.com/mmouterde/mocha-sonarqube-reporter) | Yes | `reports/node-test.sonar.xml` | [SonarQube unit tests integration](https://docs.sonarqube.org/latest/analysis/generic-test/) _(generic SonarQube format)_ | +| istanbul [lcovonly](https://istanbul.js.org/docs/advanced/alternative-reporters/#lcovonly) | Yes (in `nyc` package) | `reports/lcov.info` | [SonarQube code coverage integration](https://docs.sonarqube.org/latest/analysis/test-coverage/javascript-typescript-test-coverage/) _(JS/TS LCOV format)_ | :warning: Remarks: 1. By default - unlike Jest - Mocha doesn't provide code coverage. To do so you need to install [Istanbul](https://www.npmjs.com/package/nyc) package (`nyc`): - ```shell - npm install --save-dev nyc - ``` -2. the default `xunit` Mocha reporter doesn't produce a JUnit format supported by GitLab, that's why we recommend you to use `mocha-junit-reporter` instead. -3. Mocha doesn't support multiple unit tests reporters. -So unfortunaltely, if you're using SonarQube, you'll have to choose which report you want to generate. -Another option is to use [mocha-multi-reporters](https://github.com/stanleyhlng/mocha-multi-reporters) (see documentation) + + ```shell + npm install --save-dev nyc + ``` + +2. the default `xunit` Mocha reporter doesn't produce a JUnit format supported by GitLab, that's why we recommend you to use `mocha-junit-reporter` instead. +3. Mocha doesn't support multiple unit tests reporters. + So unfortunaltely, if you're using SonarQube, you'll have to choose which report you want to generate. + Another option is to use [mocha-multi-reporters](https://github.com/stanleyhlng/mocha-multi-reporters) (see documentation) Mocha may be either configured with CLI options of using separate Mocha and `nyc` config files. @@ -211,56 +211,68 @@ Here is the required configuration with CLI options directly in the `package.jso Here is the equivalent using separate config files: -* `package.json`: - ```json - "scripts": { - "test": "npm run mocha", - "mocha": "nyc mocha test/*.js", - ... - }, +- `package.json`: + + ```json + "scripts": { + "test": "npm run mocha", + "mocha": "nyc mocha test/*.js", ... - ``` -* `.mocharc.json`: - 1. with `mocha-junit-reporter` (for GitLab): - ```json - { - "reporter": "mocha-junit-reporter", - "reporter-option": ["mochaFile=reports/node-test.xunit.xml"] - } - ``` - 2. with `mocha-sonarqube-reporter` (for SonarQube): - ```json - { - "reporter": "mocha-sonarqube-reporter", - "reporter-option": ["output=reports/node-test.sonar.xml"] - } - ``` - 3. with both (using `mocha-multi-reporters`): - ```json - { - "reporter": "mocha-multi-reporters", - "reporter-option": ["configFile=.mmr.json"] - } - ``` - With `.mmr.json`: - ```json - { - "reporterEnabled": "spec, mocha-junit-reporter, mocha-sonarqube-reporter", - "mochaJunitReporterReporterOptions": { - "mochaFile": "reports/node-test.xunit.xml" - }, - "mochaSonarqubeReporterReporterOptions": { - "output": "reports/node-test.sonar.xml" - } - } - ``` -* `.nycrc.json`: - ```json - { - "reporter": ["text", "cobertura", "lcovonly"], - "report-dir": "reports" - } - ``` + }, + ... + ``` + +- `.mocharc.json`: + + 1. with `mocha-junit-reporter` (for GitLab): + + ```json + { + "reporter": "mocha-junit-reporter", + "reporter-option": ["mochaFile=reports/node-test.xunit.xml"] + } + ``` + + 2. with `mocha-sonarqube-reporter` (for SonarQube): + + ```json + { + "reporter": "mocha-sonarqube-reporter", + "reporter-option": ["output=reports/node-test.sonar.xml"] + } + ``` + + 3. with both (using `mocha-multi-reporters`): + + ```json + { + "reporter": "mocha-multi-reporters", + "reporter-option": ["configFile=.mmr.json"] + } + ``` + + With `.mmr.json`: + + ```json + { + "reporterEnabled": "spec, mocha-junit-reporter, mocha-sonarqube-reporter", + "mochaJunitReporterReporterOptions": { + "mochaFile": "reports/node-test.xunit.xml" + }, + "mochaSonarqubeReporterReporterOptions": { + "output": "reports/node-test.sonar.xml" + } + } + ``` + +- `.nycrc.json`: + + ```json + { + "reporter": ["text", "cobertura", "lcovonly"], + "report-dir": "reports" + } + ``` #### Unit testing with Jasmine @@ -315,10 +327,10 @@ sonar.typescript.lcov.reportPaths=reports/lcov.info More info: -* [JavaScript language support](https://docs.sonarqube.org/latest/analyzing-source-code/test-coverage/javascript-typescript-test-coverage/) -* [TypeScript language support](https://docs.sonarqube.org/latest/analyzing-source-code/test-coverage/javascript-typescript-test-coverage/) -* [test coverage & execution parameters](https://docs.sonarqube.org/latest/analysis/coverage/) -* [third-party issues](https://docs.sonarqube.org/latest/analysis/external-issues/) +- [JavaScript language support](https://docs.sonarqube.org/latest/analyzing-source-code/test-coverage/javascript-typescript-test-coverage/) +- [TypeScript language support](https://docs.sonarqube.org/latest/analyzing-source-code/test-coverage/javascript-typescript-test-coverage/) +- [test coverage & execution parameters](https://docs.sonarqube.org/latest/analysis/coverage/) +- [third-party issues](https://docs.sonarqube.org/latest/analysis/external-issues/) ### `node-audit` job @@ -326,28 +338,27 @@ The Node template features a job `node-audit` that performs an audit ([npm audit It is bound to the `test` stage. -| Input / Variable | Description | Default value | -|------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------| -| `audit-disabled` / `NODE_AUDIT_DISABLED` | Set to `true` to disable npm audit | _none_ (enabled) | -| `audit-args` / `NODE_AUDIT_ARGS` | npm [audit](https://docs.npmjs.com/cli/v8/commands/npm-audit) arguments <br/> yarn [audit](https://classic.yarnpkg.com/en/docs/cli/audit) arguments <br/> pnpm [audit](https://pnpm.io/cli/audit) arguments | `--audit-level=low` | +| Input / Variable | Description | Default value | +| ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | +| `audit-disabled` / `NODE_AUDIT_DISABLED` | Set to `true` to disable npm audit | _none_ (enabled) | +| `audit-args` / `NODE_AUDIT_ARGS` | npm [audit](https://docs.npmjs.com/cli/v8/commands/npm-audit) arguments <br/> yarn [audit](https://classic.yarnpkg.com/en/docs/cli/audit) arguments <br/> pnpm [audit](https://pnpm.io/cli/audit) arguments | `--audit-level=low` | In addition to a textual report in the console, this job produces the following report, kept for one day: -| Report | Format | Usage | -| -------------- | ---------------------------------------------------------------------------- | ----------------- | +| Report | Format | Usage | +| ------------------------------------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `$NODE_PROJECT_DIR/reports/npm-audit.native.json` | [JSON](https://docs.npmjs.com/cli/v9/commands/npm-audit#json) | [DefectDojo integration](https://documentation.defectdojo.com/integrations/parsers/#npm-audit)<br/>_This report is generated only if DefectDojo template is detected, if needed, you can force it with `$DEFECTDOJO_NPMAUDIT_REPORTS`_ | - ### `node-outdated` job The Node template features a job `node-outdated` that performs outdated analysis ([npm outdated](https://docs.npmjs.com/cli/v8/commands/npm-outdated), [yarn outdated](https://classic.yarnpkg.com/lang/en/docs/cli/outdated/) or [pnpm outdated](https://pnpm.io/cli/outdated) to find dependencies that might be updated. It is bound to the `test` stage. -| Input / Variable | Description | Default value | -|---------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------| -| `outdated-disabled` / `NODE_OUTDATED_DISABLED` | Set to `true` to disable npm outdated | _none_ (enabled) | -| `outdated-args` / `NODE_OUTDATED_ARGS` | npm [outdated](https://docs.npmjs.com/cli/v8/commands/npm-outdated) arguments <br/> yarn [outdated](https://classic.yarnpkg.com/lang/en/docs/cli/outdated/) arguments <br/> pnpm [outdated](https://pnpm.io/cli/outdated) arguments | `--long` | +| Input / Variable | Description | Default value | +| ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| `outdated-disabled` / `NODE_OUTDATED_DISABLED` | Set to `true` to disable npm outdated | _none_ (enabled) | +| `outdated-args` / `NODE_OUTDATED_ARGS` | npm [outdated](https://docs.npmjs.com/cli/v8/commands/npm-outdated) arguments <br/> yarn [outdated](https://classic.yarnpkg.com/lang/en/docs/cli/outdated/) arguments <br/> pnpm [outdated](https://pnpm.io/cli/outdated) arguments | `--long` | The job generates an outdated report that you will find here: `NODE_PROJECT_DIR/reports/npm-outdated-report.json`. @@ -357,27 +368,27 @@ The Node template features a job `node-semgrep` that performs a [Semgrep](https: It is bound to the `test` stage, and uses the following variables: -| Input / Variable | Description | Default value | -| ----------------------- | -------------------------------------- | ----------------- | -| `semgrep-disabled` / `NODE_SEMGREP_DISABLED` | Set to `true` to disable this job | _none_ | -| `semgrep-image` / `NODE_SEMGREP_IMAGE` | The Docker image used to run [Semgrep](https://semgrep.dev/docs/) | `registry.hub.docker.com/semgrep/semgrep:latest` | -| `semgrep-args` / `NODE_SEMGREP_ARGS` | Semgrep [scan options](https://semgrep.dev/docs/cli-reference#semgrep-scan-command-options) | `--metrics off --disable-version-check --no-suppress-errors` | -| `semgrep-rules` / `NODE_SEMGREP_RULES` | Space-separated list of [Semgrep rules](https://semgrep.dev/docs/running-rules).<br/>Can be both local YAML files or remote rules from the [Semgrep Registry](https://semgrep.dev/explore) (denoted by the `p/` prefix). | `p/javascript p/eslint p/gitlab-eslint` | -| `semgrep-registry-base-url` / `NODE_SEMGREP_REGISTRY_BASE_URL` | The Semgrep Registry base URL that is used to download the rules. No trailing slash. | `https://semgrep.dev/c` | -| `semgrep-download-rules-enabled` / `NODE_SEMGREP_DOWNLOAD_RULES_ENABLED` | Download Semgrep remote rules | `true` | +| Input / Variable | Description | Default value | +| ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------ | +| `semgrep-disabled` / `NODE_SEMGREP_DISABLED` | Set to `true` to disable this job | _none_ | +| `semgrep-image` / `NODE_SEMGREP_IMAGE` | The Docker image used to run [Semgrep](https://semgrep.dev/docs/) | `registry.hub.docker.com/semgrep/semgrep:latest` | +| `semgrep-args` / `NODE_SEMGREP_ARGS` | Semgrep [scan options](https://semgrep.dev/docs/cli-reference#semgrep-scan-command-options) | `--metrics off --disable-version-check --no-suppress-errors` | +| `semgrep-rules` / `NODE_SEMGREP_RULES` | Space-separated list of [Semgrep rules](https://semgrep.dev/docs/running-rules).<br/>Can be both local YAML files or remote rules from the [Semgrep Registry](https://semgrep.dev/explore) (denoted by the `p/` prefix). | `p/javascript p/eslint p/gitlab-eslint` | +| `semgrep-registry-base-url` / `NODE_SEMGREP_REGISTRY_BASE_URL` | The Semgrep Registry base URL that is used to download the rules. No trailing slash. | `https://semgrep.dev/c` | +| `semgrep-download-rules-enabled` / `NODE_SEMGREP_DOWNLOAD_RULES_ENABLED` | Download Semgrep remote rules | `true` | -> :information_source: Semgrep may [collect some metrics](https://semgrep.dev/docs/metrics), especially when using rules from the Semgrep Registry. +> :information_source: Semgrep may [collect some metrics](https://semgrep.dev/docs/metrics), especially when using rules from the Semgrep Registry. > To protect your privacy and let you run Semgrep in air-gap environments, this template disables all Semgrep metrics by default: > -> * rules from the Semgrep registry are pre-downloaded and passed to Semgrep as local rule files (can be disabled by setting `semgrep-download-rules-enabled` / `NODE_SEMGREP_DOWNLOAD_RULES_ENABLED` to `false`), -> * the `--metrics` option is set to `off`, -> * the `--disable-version-check` option is set. +> - rules from the Semgrep registry are pre-downloaded and passed to Semgrep as local rule files (can be disabled by setting `semgrep-download-rules-enabled` / `NODE_SEMGREP_DOWNLOAD_RULES_ENABLED` to `false`), +> - the `--metrics` option is set to `off`, +> - the `--disable-version-check` option is set. In addition to a textual report in the console, this job produces the following reports, kept for one day: -| Report | Format | Usage | -| -------------- | ---------------------------------------------------------------------------- | ----------------- | -| `$NODE_PROJECT_DIR/reports/node-semgrep.gitlab.json` | [GitLab's SAST format](https://semgrep.dev/docs/cli-reference#semgrep-scan-command-options) | [GitLab integration](https://docs.gitlab.com/ee/ci/yaml/artifacts_reports.html#artifactsreportssast) | +| Report | Format | Usage | +| ---------------------------------------------------- | -------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `$NODE_PROJECT_DIR/reports/node-semgrep.gitlab.json` | [GitLab's SAST format](https://semgrep.dev/docs/cli-reference#semgrep-scan-command-options) | [GitLab integration](https://docs.gitlab.com/ee/ci/yaml/artifacts_reports.html#artifactsreportssast) | | `$NODE_PROJECT_DIR/reports/node-semgrep.native.json` | [Semgrep's JSON format](https://semgrep.dev/docs/cli-reference#semgrep-scan-command-options) | [DefectDojo integration](https://documentation.defectdojo.com/integrations/parsers/file/semgrep)<br/>_This report is generated only if DefectDojo template is detected_ | ### `node-sbom` job @@ -386,11 +397,11 @@ This job generates a [SBOM](https://cyclonedx.org/) file listing installed packa It is bound to the `test` stage, and uses the following variables: -| Input / Variable | Description | Default value | -| --------------------- | -------------------------------------- | ----------------- | -| `sbom-disabled` / `NODE_SBOM_DISABLED` | Set to `true` to disable this job | _none_ | -| `sbom-version` / `NODE_SBOM_VERSION` | The version of @cyclonedx/cyclonedx-npm used to emit SBOM | _none_ (uses latest) | -| `sbom-opts` / `NODE_SBOM_OPTS` | Options for @cyclonedx/cyclonedx-npm used for SBOM analysis | `--omit dev` | +| Input / Variable | Description | Default value | +| -------------------------------------- | ----------------------------------------------------------- | -------------------- | +| `sbom-disabled` / `NODE_SBOM_DISABLED` | Set to `true` to disable this job | _none_ | +| `sbom-version` / `NODE_SBOM_VERSION` | The version of @cyclonedx/cyclonedx-npm used to emit SBOM | _none_ (uses latest) | +| `sbom-opts` / `NODE_SBOM_OPTS` | Options for @cyclonedx/cyclonedx-npm used for SBOM analysis | `--omit dev` | ### `node-publish` job @@ -401,55 +412,57 @@ When enabled, it is executed on a Git tag with a semantic versioning pattern (`v It uses the following variables: -| Input / Variable | Description | Default value | -|----------------------------|-----------------------------------------------------------------------------|-------------------| -| `publish-enabled` / `NODE_PUBLISH_ENABLED` | Set to `true` to enable the publish job | _none_ (disabled) | -| `publish-args` / `NODE_PUBLISH_ARGS` | npm [publish](https://docs.npmjs.com/cli/v8/commands/npm-publish) extra arguments<br/>yarn [publish](https://classic.yarnpkg.com/lang/en/docs/cli/publish/) extra arguments <br/>pnpm [publish](https://pnpm.io/cli/publish) extra arguments | _none_ | -| :lock: `NODE_PUBLISH_TOKEN`| npm publication registry authentication token | _none_ | +| Input / Variable | Description | Default value | +| ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | +| `publish-enabled` / `NODE_PUBLISH_ENABLED` | Set to `true` to enable the publish job | _none_ (disabled) | +| `publish-args` / `NODE_PUBLISH_ARGS` | npm [publish](https://docs.npmjs.com/cli/v8/commands/npm-publish) extra arguments<br/>yarn [publish](https://classic.yarnpkg.com/lang/en/docs/cli/publish/) extra arguments <br/>pnpm [publish](https://pnpm.io/cli/publish) extra arguments | _none_ | +| :lock: `NODE_PUBLISH_TOKEN` | npm publication registry authentication token | _none_ | #### Configure the target registry The target registry url for publication shall be configured in the `publishConfig` of your `package.json` file. Examples: -* for an unscoped package: - ```json - { - "name": "my-package", - // ... - "publishConfig": { - "registry": "https://registry.acme.corp/npm" - } - // ... +- for an unscoped package: + + ```json + { + "name": "my-package", + // ... + "publishConfig": { + "registry": "https://registry.acme.corp/npm" } - ``` -* for a scoped package: - ```json - { - "name": "@acme/my-package", - // ... - "publishConfig": { - "@acme:registry": "https://registry.acme.corp/npm" - } - // ... + // ... + } + ``` + +- for a scoped package: + + ```json + { + "name": "@acme/my-package", + // ... + "publishConfig": { + "@acme:registry": "https://registry.acme.corp/npm" } - ``` + // ... + } + ``` Then simply declare the registry authentication token with :lock: `NODE_PUBLISH_TOKEN`. -:information_source: it is not mandatory to declare the registry if you wish to use the GitLab -project-level npm packages registry (it is declared by default by the template, with the required credentials). All you have to do to is to make sure your npm package name - [uses the right scope](https://docs.gitlab.com/ee/user/packages/npm_registry/#naming-convention). +:information_source: it is not mandatory to declare the registry if you wish to use the GitLab +project-level npm packages registry (it is declared by default by the template, with the required credentials). All you have to do to is to make sure your npm package name +[uses the right scope](https://docs.gitlab.com/ee/user/packages/npm_registry/#naming-convention). For example, if your project is `https://gitlab.example.com/my-org/engineering-group/team-amazing/analytics`, the root namespace is `my-org`, and your package name must have the `@my-org` scope (probable package fullname: `@my-org/analytics`). #### Exclude resources from package Don't forget to exclude undesired folders and files from the package resources (simply add them to your `.gitignore` or `.npmignore` file): -* the `.npm/`, `.yarn/` or `.pnpm-store` folder, that is used internally by the Node template to store `npm`, `yarn` or `pnpm` cache (depending on the package manager you're actually using), -* the `reports/` folder, that is used by most _to be continuous_ to output all kind of reports, -* the Node.js build output dir (if any), -* any other undesired file & folder that you don't want to appear in your published package(s). - +- the `.npm/`, `.yarn/` or `.pnpm-store` folder, that is used internally by the Node template to store `npm`, `yarn` or `pnpm` cache (depending on the package manager you're actually using), +- the `reports/` folder, that is used by most _to be continuous_ to output all kind of reports, +- the Node.js build output dir (if any), +- any other undesired file & folder that you don't want to appear in your published package(s). ## Variants @@ -463,13 +476,13 @@ This variant allows delegating your secrets management to a [Vault](https://www. In order to be able to communicate with the Vault server, the variant requires the additional configuration parameters: -| Input / Variable | Description | Default value | -| ----------------- | -------------------------------------- | ----------------- | -| `TBC_VAULT_IMAGE` | The [Vault Secrets Provider](https://gitlab.com/to-be-continuous/tools/vault-secrets-provider) image to use (can be overridden) | `registry.gitlab.com/to-be-continuous/tools/vault-secrets-provider:latest` | -| `vault-base-url` / `VAULT_BASE_URL` | The Vault server base API url | _none_ | -| `vault-oidc-aud` / `VAULT_OIDC_AUD` | The `aud` claim for the JWT | `$CI_SERVER_URL` | -| :lock: `VAULT_ROLE_ID` | The [AppRole](https://www.vaultproject.io/docs/auth/approle) RoleID | **must be defined** | -| :lock: `VAULT_SECRET_ID` | The [AppRole](https://www.vaultproject.io/docs/auth/approle) SecretID | **must be defined** | +| Input / Variable | Description | Default value | +| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | +| `TBC_VAULT_IMAGE` | The [Vault Secrets Provider](https://gitlab.com/to-be-continuous/tools/vault-secrets-provider) image to use (can be overridden) | `registry.gitlab.com/to-be-continuous/tools/vault-secrets-provider:latest` | +| `vault-base-url` / `VAULT_BASE_URL` | The Vault server base API url | _none_ | +| `vault-oidc-aud` / `VAULT_OIDC_AUD` | The `aud` claim for the JWT | `$CI_SERVER_URL` | +| :lock: `VAULT_ROLE_ID` | The [AppRole](https://www.vaultproject.io/docs/auth/approle) RoleID | **must be defined** | +| :lock: `VAULT_SECRET_ID` | The [AppRole](https://www.vaultproject.io/docs/auth/approle) SecretID | **must be defined** | #### Usage @@ -481,9 +494,9 @@ Then you may retrieve any of your secret(s) from Vault using the following synta With: -| Parameter | Description | -| -------------------------------- | -------------------------------------- | -| `secret_path` (_path parameter_) | this is your secret location in the Vault server | +| Parameter | Description | +| -------------------------------- | --------------------------------------------------------------------- | +| `secret_path` (_path parameter_) | this is your secret location in the Vault server | | `field` (_query parameter_) | parameter to access a single basic field from the secret JSON payload | #### Example @@ -504,4 +517,4 @@ variables: NODE_CONFIG_SCOPED_REGISTRIES: "@public-repo:https://public.npm.registry/some/repo @my-priv-repo:https://private.npm.registry/another/repo" # retrieve private repo auth token from Vault NODE_REGISTRY_MY_PRIV_REPO_AUTH: "@url@http://vault-secrets-provider/api/secrets/b7ecb6ebabc231/node/priv-repo/creds?field=token" -``` \ No newline at end of file +```