Commit 6812cf7d authored by Tangui Didailler's avatar Tangui Didailler Committed by Pierre Smeyers
Browse files

feat: add pnpm support

parent 76d410a8
Loading
Loading
Loading
Loading
+12 −12
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@

This project implements a GitLab CI/CD template to build, test and analyse your JavaScript/TypeScript/[Node.js](https://nodejs.org/) projects.

More precisely, it can be used by all projects based on [npm](https://www.npmjs.com/) or [yarn](https://yarnpkg.com/) package managers.
More precisely, it can be used by all projects based on [npm](https://www.npmjs.com/), [yarn](https://yarnpkg.com/) or [pnpm](https://pnpm.io/) package managers.

## Usage

@@ -22,12 +22,12 @@ The Node.js template uses some global configuration used throughout all jobs.
| Name                   | Description                                                                                      | Default value     |
|------------------------|--------------------------------------------------------------------------------------------------|-------------------|
| `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` |
| `NODE_MANAGER`         | The package manager used by your project (npm or yarn)<br/>**If undefined, automatic detection** | _none_            |
| `NODE_MANAGER`         | The package manager used by your project (one of `npm`, `yarn` or `pnpm`)<br/>**If undefined, automatic detection** | _none_ (auto) |
| `NODE_CONFIG_REGISTRY` | Main npm [registry](https://docs.npmjs.com/cli/v8/using-npm/registry) to use                     | _none_            |
| `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_ |
| `NODE_PROJECT_DIR`     | Node project root directory                                                                      | `.`               |
| `NODE_SOURCE_DIR`      | Sources directory                                                                                | `src`             |
| `NODE_INSTALL_EXTRA_OPTS`| Extra options to install project dependencies (either [`npm ci`](https://docs.npmjs.com/cli/ci.html/) or [`yarn install`](https://yarnpkg.com/cli/install)) | _none_ |
| `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

@@ -73,7 +73,7 @@ It is bound to the `test` stage, and uses the following variable:
| Name                     | Description                                                                                                                                                                                                                | Default value                 |
|--------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------|
| `NODE_LINT_ENABLED`      | Set to `true` to enable lint analysis                                                                                                                                                                                      | _none_ (disabled)             |
| `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 | `run lint`                    |
| `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`.

@@ -90,8 +90,8 @@ This job is bound to the `build` stage, and uses the following variables:
|-------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------|
| `NODE_BUILD_DISABLED`         | Set to `true` to disable build                                                                                                                                    | _none_ (enabled)      |
| `NODE_BUILD_DIR`              | Variable to define build directory                                                                                                                                | `dist`                |
| `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  | `run build --prod`    |
| `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                   | `test -- --coverage`  |
| `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 | `run build --prod`    |
| `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
@@ -297,14 +297,14 @@ More info:

### `node-audit` job

The Node template features a job `node-audit` that performs an audit ([npm audit](https://docs.npmjs.com/cli/v8/commands/npm-audit) or [yarn audit](https://classic.yarnpkg.com/en/docs/cli/audit)) to find vulnerabilities (security).
The Node template features a job `node-audit` that performs an audit ([npm audit](https://docs.npmjs.com/cli/v8/commands/npm-audit), [yarn audit](https://classic.yarnpkg.com/en/docs/cli/audit) or [pnpm audit](https://pnpm.io/cli/audit)) to find vulnerabilities (security).

It is bound to the `test` stage.

| Name                   | Description                                                                                                                                           | Default value                    |
|------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------|
| `NODE_AUDIT_DISABLED`  | Set to `true` to disable npm audit                                                                                                                    | _none_ (enabled)                 |
| `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   | `--audit-level=low`              |
| `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:

@@ -315,14 +315,14 @@ In addition to a textual report in the console, this job produces the following

### `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) or [yarn outdated](https://classic.yarnpkg.com/lang/en/docs/cli/outdated/)) to find dependencies that might be updated.
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.

| Name                      | Description                                                                                                                                                           | Default value                      |
|---------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------|
| `NODE_OUTDATED_DISABLED`  | Set to `true` to disable npm outdated                                                                                                                                 | _none_ (enabled)                   |
| `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 | `--long`                           |
| `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`.

@@ -350,7 +350,7 @@ It uses the following variables:
| Name                       | Description                                                                 | Default value     |
|----------------------------|-----------------------------------------------------------------------------|-------------------|
| `NODE_PUBLISH_ENABLED`     | Set to `true` to enable the publish job                                     | _none_ (disabled) |
| `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 | _none_ |
| `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
@@ -391,7 +391,7 @@ For example, if your project is `https://gitlab.example.com/my-org/engineering-g

Don't forget to exclude undesired folders and files from the package resources (simply add them to your `.gitignore` or `.npmignore` file):

* the `.npm/` or `.yarn/` folder, that is used internally by the Node template to store `npm` or `yarn` cache (depending on the package manager you're actually using),
* 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).
+11 −9
Original line number Diff line number Diff line
@@ -17,8 +17,10 @@
    },
    {
      "name": "NODE_MANAGER",
      "description": "The package manager used by your project (npm or yarn) - **if undefined, automatic detection**",
      "default": "none",
      "description": "The package manager used by your project (npm, yarn or pnpm) - **if undefined, automatic detection**",
      "default": "auto",
      "type": "enum",
      "values": ["auto", "npm", "yarn", "pnpm"],
      "advanced": true
    },
    {
@@ -40,7 +42,7 @@
    },
    {
      "name": "NODE_BUILD_ARGS",
      "description": "npm [run script](https://docs.npmjs.com/cli/v8/commands/npm-run-script) arguments - yarn [run script](https://classic.yarnpkg.com/en/docs/cli/run) arguments",
      "description": "npm [run script](https://docs.npmjs.com/cli/v8/commands/npm-run-script) arguments - yarn [run script](https://classic.yarnpkg.com/en/docs/cli/run) arguments - pnpm [run script](https://pnpm.io/cli/run) arguments",
      "default": "run build --prod",
      "advanced": true
    },
@@ -52,13 +54,13 @@
    },
    {
      "name": "NODE_TEST_ARGS",
      "description": "npm [test](https://docs.npmjs.com/cli/v8/commands/npm-test) arguments - yarn [test](https://classic.yarnpkg.com/en/docs/cli/test) arguments",
      "description": "npm [test](https://docs.npmjs.com/cli/v8/commands/npm-test) arguments - yarn [test](https://classic.yarnpkg.com/en/docs/cli/test) arguments - pnpm [test](https://pnpm.io/cli/test) arguments",
      "default": "test -- --coverage",
      "advanced": true
    },
    {
      "name": "NODE_INSTALL_EXTRA_OPTS",
      "description": "Extra options to install project dependencies (either [`npm ci`](https://docs.npmjs.com/cli/ci.html/) or [`yarn install`](https://yarnpkg.com/cli/install))",
      "description": "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))",
      "advanced": true
    }
  ],
@@ -71,7 +73,7 @@
      "variables": [
        {
          "name": "NODE_LINT_ARGS",
          "description": "npm [run script](https://docs.npmjs.com/cli/v8/commands/npm-run-script) arguments to execute the lint analysis - yarn [run script](https://classic.yarnpkg.com/en/docs/cli/run) arguments to execute the lint analysis",
          "description": "npm [run script](https://docs.npmjs.com/cli/v8/commands/npm-run-script) arguments to execute the lint analysis - yarn [run script](https://classic.yarnpkg.com/en/docs/cli/run) arguments to execute the lint analysis - pnpm [run script](https://pnpm.io/cli/run) arguments to execute the lint analysis",
          "default": "run lint",
          "advanced": true
        }
@@ -85,7 +87,7 @@
      "variables": [
        {
          "name": "NODE_AUDIT_ARGS",
          "description": "npm [audit](https://docs.npmjs.com/cli/v8/commands/npm-audit) arguments - yarn [audit](https://classic.yarnpkg.com/en/docs/cli/audit) arguments",
          "description": "npm [audit](https://docs.npmjs.com/cli/v8/commands/npm-audit) arguments - yarn [audit](https://classic.yarnpkg.com/en/docs/cli/audit) arguments - [pnpm audit](https://pnpm.io/cli/audit) arguments",
          "default": "--audit-level=low"
        }
      ]
@@ -98,7 +100,7 @@
      "variables": [
        {
          "name": "NODE_OUTDATED_ARGS",
          "description": "npm [outdated](https://docs.npmjs.com/cli/v8/commands/npm-outdated) arguments - yarn [outdated](https://classic.yarnpkg.com/lang/en/docs/cli/outdated/) arguments",
          "description": "npm [outdated](https://docs.npmjs.com/cli/v8/commands/npm-outdated) arguments - yarn [outdated](https://classic.yarnpkg.com/lang/en/docs/cli/outdated/) arguments - pnpm [outdated](https://pnpm.io/cli/outdated) arguments",
          "default": "--long"
        }
      ]
@@ -130,7 +132,7 @@
      "variables": [
        {
          "name": "NODE_PUBLISH_ARGS",
          "description": "npm [publish](https://docs.npmjs.com/cli/v8/commands/npm-publish) extra arguments - yarn [publish](https://classic.yarnpkg.com/lang/en/docs/cli/publish/) extra arguments",
          "description": "npm [publish](https://docs.npmjs.com/cli/v8/commands/npm-publish) extra arguments - yarn [publish](https://classic.yarnpkg.com/lang/en/docs/cli/publish/) extra arguments - pnpm [publish](https://pnpm.io/cli/publish) extra arguments",
          "advanced": true
        },
        {
+23 −1
Original line number Diff line number Diff line
@@ -272,6 +272,10 @@ stages:
      log_info "--- Build system explictly declared: yarn"
      return
      ;;
    pnpm)
      log_info "--- Build system explictly declared: pnpm"
      return
      ;;
    *)
      log_warn "--- Unknown declared node manager system: \\e[33;1m${NODE_MANAGER}\\e[0m: please read template doc"
      ;;
@@ -285,6 +289,10 @@ stages:
    then
      log_info "--- Build system auto-detected: yarn"
      export NODE_MANAGER="yarn"
    elif [[ -f "pnpm-locK.yaml" ]]
    then
      log_info "--- Build system auto-detected: pnpm"
      export NODE_MANAGER="pnpm"
    else
      log_error "--- Node manager system auto-detect failed: please read template doc"
      exit 1
@@ -365,6 +373,13 @@ stages:
    fi
  }

  function check_pnpm_installation() {
    if ! command -v pnpm >/dev/null; then
      log_info "--- pnpm not found: installing it"
      npm install -g pnpm
    fi
  }

  unscope_variables

  # ENDSCRIPT
@@ -391,6 +406,7 @@ stages:
    - install_ca_certs "${CUSTOM_CA_CERTS:-$DEFAULT_CA_CERTS}"
    - cd ${NODE_PROJECT_DIR}
    - guess_node_manager_system
    - if [ "$NODE_MANAGER" = "pnpm" ]; then check_pnpm_installation; fi
    - config_registry=${NODE_CONFIG_REGISTRY:-$NPM_CONFIG_REGISTRY}
    # NPM_CONFIG_REGISTRY is not supported by old npm versions: force with cli
    - if [[ "$config_registry" ]]; then $NODE_MANAGER config set registry $config_registry; fi
@@ -523,7 +539,13 @@ node-sbom:
  dependencies: []
  script:
    - mkdir -p -m 777 reports
    - npx -y @cyclonedx/cyclonedx-npm${NODE_SBOM_VERSION:+@$NODE_SBOM_VERSION} --output-format JSON --output-file reports/node-sbom.cyclonedx.json $NODE_SBOM_OPTS
    - |
      if [ "$NODE_MANAGER" = 'pnpm' ]
      then
        pnpm dlx @cyclonedx/cdxgen${NODE_SBOM_VERSION:+@$NODE_SBOM_VERSION} --output reports/node-sbom.cyclonedx.json $NODE_SBOM_OPTS
      else
        npx -y @cyclonedx/cyclonedx-npm${NODE_SBOM_VERSION:+@$NODE_SBOM_VERSION} --output-format JSON --output-file reports/node-sbom.cyclonedx.json $NODE_SBOM_OPTS
      fi
    - chmod a+r reports/node-sbom.cyclonedx.json
  artifacts:
    name: "SBOM for Node from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG"