Injecting orb source into configuration. Modified config: version: 2.1 orbs: node: version: 2.1 description: | Easily install Node.js and its package managers (npm, yarn, yarn-berry, pnpm, bun). Best of all, install your packages with caching enabled by default. Supports Linux x86_64, MacOS, and Arm64 V8. display: home_url: https://nodejs.org/ source_url: https://github.com/circleci-public/node-orb commands: install: description: | Install custom versions of Node.js, and optionally NPM/pnpm/Yarn, in any execution environment (Docker/Linux, macOS, machine) that does not have it preinstalled. Recommendation: It is highly recommended to utilize an environment such as Docker with Node preinstalled. parameters: bun-version: default: "" description: | Pick a version of Bun to install (if no version is specified, the latest stable version will be installed): https://github.com/oven-sh/bun/releases type: string install-bun: default: false description: Install Bun? type: boolean install-pnpm: default: false description: Install pnpm? type: boolean install-yarn: default: false description: Install Yarn? type: boolean node-version: default: "" description: | Specify the full version tag to install. To install the latest version, set the version to `latest`. If unspecified, the version listed in .nvmrc or .node-version will be installed. If no .nvmrc file and .node-version file exists the active LTS version of Node.js will be installed by default. For a full list of releases, see the following: https://nodejs.org/en/download/releases type: string nvm-cache-key: default: nvm-v1-cache description: | Cache key to use when downloading nodejs. This is only used when use-nvm-cache is set to true. Defaults to nvm-v1-cache, update this value if you need to restart the cache. The node-version is added by default at the end of the cache key. If you are using multiple executors, add the executor as part of the key. type: string pnpm-version: default: "" description: | Pick a version of pnpm to install (if no version is specified, the latest stable version will be installed): https://github.com/pnpm/pnpm/releases type: string use-nvm-cache: default: true description: | Indicates if cache would be used when installing nodejs, this would reduce the amount of errors when downloading the binaries. Defaults to true. type: boolean yarn-version: default: "" description: | Pick a version of Yarn to install (if no version is specified, the latest stable version will be installed): https://github.com/yarnpkg/yarn/releases type: string steps: - when: condition: <> steps: - restore_cache: keys: - <>-<>-{{ arch }} name: Restore Nvm Cache - run: command: "#!/usr/bin/env bash\n# shellcheck disable=SC2016\n\n# Only install nvm if it's not already installed\nif command -v nvm &> /dev/null; then\n echo \"nvm is already installed. Skipping nvm install.\";\nelse\n curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash;\n \n echo 'export NVM_DIR=\"$HOME/.nvm\"' >> \"$BASH_ENV\";\n echo '[ -s \"$NVM_DIR/nvm.sh\" ] && \\. \"$NVM_DIR/nvm.sh\" --no-use' >> \"$BASH_ENV\";\n \n # shellcheck source=/dev/null\n source \"$BASH_ENV\";\nfi\n\n# See: https://github.com/nvm-sh/nvm#usage\nif [ \"$NODE_PARAM_VERSION\" = \"latest\" ]; then\n # When no version is specified we default to the latest version of Node\n NODE_ORB_INSTALL_VERSION=$(nvm ls-remote | tail -n1 | grep -Eo 'v[0-9]+\\.[0-9]+\\.[0-9]+')\n nvm install -b \"$NODE_ORB_INSTALL_VERSION\" # aka nvm install node. We're being explicit here.\n nvm alias default \"$NODE_ORB_INSTALL_VERSION\"\nelif [ -n \"$NODE_PARAM_VERSION\" ] && [ \"$NODE_PARAM_VERSION\" != \"lts\" ]; then\n nvm install -b \"$NODE_PARAM_VERSION\"\n nvm alias default \"$NODE_PARAM_VERSION\"\nelif [ -f \".nvmrc\" ]; then\n NVMRC_SPECIFIED_VERSION=$(<.nvmrc)\n nvm install -b \"$NVMRC_SPECIFIED_VERSION\"\n nvm alias default \"$NVMRC_SPECIFIED_VERSION\"\nelif [ -f \".node-version\" ]; then\n NVMRC_SPECIFIED_VERSION=$(<.node-version)\n nvm install \"$NVMRC_SPECIFIED_VERSION\"\n nvm alias default \"$NVMRC_SPECIFIED_VERSION\"\nelse\n nvm install -b --lts\n nvm alias default lts/*\nfi\n\necho 'nvm use default &>/dev/null' >> \"$BASH_ENV\"\n" environment: NODE_PARAM_VERSION: <> name: Install Node.js <> - when: condition: <> steps: - save_cache: key: <>-<>-{{ arch }} name: Save Nvm Cache paths: - ~/.nvm/.cache - /opt/circleci/.nvm/.cache - when: condition: <> steps: - install-pnpm: version: <> - when: condition: <> steps: - install-yarn: version: <> - when: condition: <> steps: - install-bun: version: <> install-bun: description: | Install a custom version of the Bun package manager parameters: version: default: "" description: | Pick a version of Bun to install (if no version is specified, the latest stable version will be installed): https://github.com/oven-sh/bun/releases type: string steps: - run: command: | #!/usr/bin/env bash if [[ $EUID == 0 ]]; then export SUDO=""; else export SUDO="sudo"; fi # FUNCTIONS get_bun_version () { if [[ "$NODE_PARAM_BUN_VERSION" == "" ]]; then BUN_ORB_VERSION=$(curl --fail --retry 5 -Ls -o /dev/null -w '%{url_effective}' "https://github.com/oven-sh/bun/releases/latest" | sed 's:.*/bun-v::') echo "Latest version of Bun is $BUN_ORB_VERSION" else BUN_ORB_VERSION="$NODE_PARAM_BUN_VERSION" echo "Selected version of Bun is $BUN_ORB_VERSION" fi } installation_check () { echo "Checking if Bun is already installed..." if command -v bun > /dev/null 2>&1; then if bun --version | grep "$BUN_ORB_VERSION" > /dev/null 2>&1; then echo "Bun $BUN_ORB_VERSION is already installed" exit 0 else echo "A different version of Bun is installed ($(bun --version)); removing it" # Remove existing bun installation $SUDO rm -rf "$HOME/.bun" > /dev/null 2>&1 $SUDO npm rm -g bun > /dev/null 2>&1 fi fi } # cd to home so that bun --version will not use relative installed bun cd ~ || echo "Cannot change directory to home directory, bun version may be mismatched." get_bun_version installation_check # install bun echo "Installing Bun v$BUN_ORB_VERSION" if [ -w "$(npm root -g)" ]; then npm install -g "bun@$BUN_ORB_VERSION" else $SUDO npm install -g "bun@$BUN_ORB_VERSION" fi # test/verify version echo "Verifying Bun install" if bun --version | grep "$BUN_ORB_VERSION" > /dev/null 2>&1; then echo "Success! Bun $(bun --version) has been installed to $(command -v bun)" else echo "Something went wrong; the specified version of Bun could not be installed" exit 1 fi environment: NODE_PARAM_BUN_VERSION: <> name: Install Bun install-packages: description: | Install your Node packages with automated caching and best practices applied. Requires lock file. parameters: app-dir: default: . description: Path to the directory containing your package.json file. Not needed if package.json lives in the root. type: string cache-only-lockfile: default: true description: | If true, package.json will be ignored in the cache key. Useful for projects where package.json changes do not always invalidate dependencies. Note: package.json will still be the final fallback key incase a project is not configured with a lock file. type: boolean cache-path: default: "" description: | By default, this orb will cache '~/.npm' for npm, '~/.bun/install/cache' for bun, and 'node_modules' for yarn/pnpm. Override which path to cache with this parameter. The cache will be ignored when using npm ci, as the command doesn't benefit from cache. type: string cache-version: default: v1 description: Change the default cache version if you need to clear the cache for any reason. type: string check-cache: default: never description: | Yarn berry only for Zero install support - Use 'always' to always --check-cache argument to yarn install. Use 'detect' to enable caching of yarn.lock and to only add when required. enum: - never - always - detect type: enum include-branch-in-cache-key: default: false description: | If true, this cache bucket will only apply to jobs within the same branch. type: boolean override-ci-command: default: "" description: | By default, packages will be installed with "npm ci", "yarn install --frozen-lockfile", "yarn install --immutable", "pnpm install --frozen-lockfile", or "bun install --frozen-lockfile". Optionally supply a custom package installation command, with any additional flags needed. When the command npm ci is used, no cache will be used, as the command doesn't benefit from it. type: string pkg-manager: default: npm description: | Select the default node package manager to use. NPM v5+ Required. To use yarn-berry your package.json must have packageManager set to a yarn berry version, otherwise it will use old yarn. enum: - npm - yarn - yarn-berry - pnpm - bun type: enum with-cache: default: true description: | Cache your node packages automatically for faster install times. Cache will be ignored when using npm ci. type: boolean steps: - run: command: |- #!/usr/bin/env bash # Fail if package.json does not exist in working directory if [ ! -f "package.json" ]; then echo echo "---" echo "Unable to find your package.json file. Did you forget to set the app-dir parameter?" echo "---" echo echo "Current directory: $(pwd)" echo echo echo "List directory: " echo ls exit 1 fi name: Checking for package.json working_directory: <> - when: condition: and: - << parameters.with-cache >> - or: - not: equal: - npm - << parameters.pkg-manager >> - and: - << parameters.override-ci-command >> - not: equal: - npm-ci - << parameters.override-ci-command >> steps: - run: command: | #!/usr/bin/env bash TARGET_DIR="/tmp" if [ -n "$HOMEDRIVE" ]; then TARGET_DIR="$HOMEDRIVE\\tmp" fi # Link corresponding lock file to a temporary file used by cache commands if [ -f "package-lock.json" ]; then echo "Found package-lock.json file, assuming lockfile" cp package-lock.json "$TARGET_DIR"/node-project-lockfile elif [ -f "npm-shrinkwrap.json" ]; then echo "Found npm-shrinkwrap.json file, assuming lockfile" cp npm-shrinkwrap.json "$TARGET_DIR"/node-project-lockfile elif [ -f "yarn.lock" ]; then echo "Found yarn.lock file, assuming lockfile" cp yarn.lock "$TARGET_DIR"/node-project-lockfile elif [ -f "pnpm-lock.yaml" ]; then echo "Found pnpm-lock.yaml file, assuming lockfile" cp pnpm-lock.yaml "$TARGET_DIR"/node-project-lockfile elif [ -f "bun.lock" ]; then echo "Found bun.lock file, assuming lockfile" # Check if both bun.lock and bun.lockb exist and provide helpful guidance if [ -f "bun.lockb" ]; then echo "Warning: Both bun.lock and bun.lockb are present. Because bun.lock exists, bun.lockb will be ignored." echo "To clear this warning, remove one of these two files." echo "The bun.lockb format is still supported by bun, but may be removed in the future." fi cp bun.lock "$TARGET_DIR"/node-project-lockfile elif [ -f "bun.lockb" ]; then echo "Found bun.lockb file, assuming lockfile" cp bun.lockb "$TARGET_DIR"/node-project-lockfile else echo "Found no lockfile, adding empty one" touch "$TARGET_DIR"/node-project-lockfile fi cp package.json "$TARGET_DIR"/node-project-package.json name: Determine lockfile working_directory: <> - restore_cache: keys: - node-deps-{{ arch }}-<>-<<#parameters.include-branch-in-cache-key>>{{ .Branch }}-<><<^parameters.cache-only-lockfile>>{{ checksum "/tmp/node-project-package.json" }}-<>{{ checksum "/tmp/node-project-lockfile" }} - node-deps-{{ arch }}-<>-<<#parameters.include-branch-in-cache-key>>{{ .Branch }}-<>{{ checksum "/tmp/node-project-package.json" }} - node-deps-{{ arch }}-<>-<<#parameters.include-branch-in-cache-key>>{{ .Branch }}-<> - when: condition: equal: - npm - << parameters.pkg-manager >> steps: - run: command: |- #!/usr/bin/env bash # Configure npm cache path if provided if [[ -n "$PARAM_CACHE_PATH" ]] && [[ "$PARAM_OVERRIDE_COMMAND" != "npm ci" ]] && [[ -n "$PARAM_OVERRIDE_COMMAND" ]]; then npm config set cache "$PARAM_CACHE_PATH" fi # Run override ci command if provided, otherwise run default npm install if [[ -n "$PARAM_OVERRIDE_COMMAND" ]]; then echo "Running override package installation command:" eval "$PARAM_OVERRIDE_COMMAND" else npm ci fi environment: PARAM_CACHE_PATH: << parameters.cache-path >> PARAM_OVERRIDE_COMMAND: << parameters.override-ci-command >> name: Installing NPM packages working_directory: <> - when: condition: and: - << parameters.with-cache >> - << parameters.override-ci-command >> - not: equal: - npm-ci - << parameters.override-ci-command >> steps: - when: condition: << parameters.cache-path >> steps: - save_cache: key: node-deps-{{ arch }}-<>-<<#parameters.include-branch-in-cache-key>>{{ .Branch }}-<><<^parameters.cache-only-lockfile>>{{ checksum "/tmp/node-project-package.json" }}-<>{{ checksum "/tmp/node-project-lockfile" }} paths: - << parameters.cache-path >> - unless: condition: << parameters.cache-path >> steps: - save_cache: key: node-deps-{{ arch }}-<>-<<#parameters.include-branch-in-cache-key>>{{ .Branch }}-<><<^parameters.cache-only-lockfile>>{{ checksum "/tmp/node-project-package.json" }}-<>{{ checksum "/tmp/node-project-lockfile" }} paths: - ~/.npm - when: condition: equal: - pnpm - << parameters.pkg-manager >> steps: - run: command: | #!/usr/bin/env bash # Run override ci command if provided, otherwise run default npm install if [[ -n "$PARAM_OVERRIDE_COMMAND" ]]; then echo "Running override package installation command:" eval "$PARAM_OVERRIDE_COMMAND" else pnpm install --frozen-lockfile fi environment: PARAM_CACHE_PATH: << parameters.cache-path >> PARAM_OVERRIDE_COMMAND: << parameters.override-ci-command >> name: Installing PNPM packages working_directory: <> - when: condition: << parameters.with-cache >> steps: - when: condition: << parameters.cache-path >> steps: - save_cache: key: node-deps-{{ arch }}-<>-<<#parameters.include-branch-in-cache-key>>{{ .Branch }}-<><<^parameters.cache-only-lockfile>>{{ checksum "/tmp/node-project-package.json" }}-<>{{ checksum "/tmp/node-project-lockfile" }} paths: - <> - unless: condition: << parameters.cache-path >> steps: - save_cache: key: node-deps-{{ arch }}-<>-<<#parameters.include-branch-in-cache-key>>{{ .Branch }}-<><<^parameters.cache-only-lockfile>>{{ checksum "/tmp/node-project-package.json" }}-<>{{ checksum "/tmp/node-project-lockfile" }} paths: - <>/node_modules - when: condition: equal: - yarn - << parameters.pkg-manager >> steps: - run: command: |- #!/usr/bin/env bash # Run override ci command if provided, otherwise run default yarn install if [[ -n "$PARAM_OVERRIDE_COMMAND" ]]; then echo "Running override package installation command:" eval "$PARAM_OVERRIDE_COMMAND" else yarn install --frozen-lockfile fi environment: PARAM_OVERRIDE_COMMAND: << parameters.override-ci-command >> YARN_CACHE_FOLDER: << parameters.cache-path >> name: Installing YARN packages working_directory: <> - when: condition: << parameters.with-cache >> steps: - when: condition: << parameters.cache-path >> steps: - save_cache: key: node-deps-{{ arch }}-<>-<<#parameters.include-branch-in-cache-key>>{{ .Branch }}-<><<^parameters.cache-only-lockfile>>{{ checksum "/tmp/node-project-package.json" }}-<>{{ checksum "/tmp/node-project-lockfile" }} paths: - <> - unless: condition: << parameters.cache-path >> steps: - save_cache: key: node-deps-{{ arch }}-<>-<<#parameters.include-branch-in-cache-key>>{{ .Branch }}-<><<^parameters.cache-only-lockfile>>{{ checksum "/tmp/node-project-package.json" }}-<>{{ checksum "/tmp/node-project-lockfile" }} paths: - <>/node_modules - when: condition: equal: - yarn-berry - << parameters.pkg-manager >> steps: - when: condition: equal: - detect - << parameters.check-cache >> steps: - restore_cache: keys: - yarn-berry-{{ arch }}-<>-<<#parameters.include-branch-in-cache-key>>{{ .Branch }}-<>{{ checksum "/tmp/yarn-zero-lockfile" }} - yarn-berry-{{ arch }}-<>-<<#parameters.include-branch-in-cache-key>>{{ .Branch }}-<> - run: command: |- #!/usr/bin/env bash if ! corepack enable; then echo "Using alternative corepack location" corepack enable --install-directory ~/bin fi # Run override ci command if provided, otherwise run default yarn install # See: https://yarnpkg.com/configuration/yarnrc/#cacheFolder if [[ -n "$PARAM_CACHE_PATH" ]]; then yarn config set cacheFolder "$PARAM_CACHE_PATH" fi if [[ -n "$PARAM_OVERRIDE_COMMAND" ]]; then echo "Running override package installation command:" eval "$PARAM_OVERRIDE_COMMAND" else # If a cache folder is already present, then we use Yarn Zero installs # See: https://yarnpkg.com/features/zero-installs if [[ -e "$PARAM_CACHE_PATH" ]]; then # See: https://yarnpkg.com/features/zero-installs#does-it-have-security-implications YARN_LOCKFILE_PATH="/tmp/yarn-zero-lockfile" if [[ "$PARAM_CHECK_CACHE" == "detect" ]]; then if [[ ! -f "$YARN_LOCKFILE_PATH" ]]; then echo "No yarn zero lockfile cached. Enabling check cache this run." ENABLE_CHECK_CACHE="true" elif [[ $(diff -q "$YARN_LOCKFILE_PATH" yarn.lock) ]]; then echo "Detected changes in lockfile. Enabling check cache this run." rm -f "$YARN_LOCKFILE_PATH" ENABLE_CHECK_CACHE="true" else echo "No changes detected in lockfile. Skipping check cache this run." fi fi if [[ "$PARAM_CHECK_CACHE" == "always" || -n "$ENABLE_CHECK_CACHE" ]]; then set -- "$@" --check-cache fi echo y | yarn install --immutable --immutable-cache "$@" if [[ "$PARAM_CHECK_CACHE" == "detect" && -n "$ENABLE_CHECK_CACHE" ]]; then cp yarn.lock "$YARN_LOCKFILE_PATH" fi else echo y | yarn install --immutable fi fi environment: PARAM_CACHE_PATH: << parameters.cache-path >> PARAM_CHECK_CACHE: << parameters.check-cache >> PARAM_OVERRIDE_COMMAND: << parameters.override-ci-command >> name: Installing YARN packages working_directory: <> - when: condition: equal: - detect - << parameters.check-cache >> steps: - save_cache: key: yarn-berry-{{ arch }}-<>-<<#parameters.include-branch-in-cache-key>>{{ .Branch }}-<>{{ checksum "/tmp/yarn-zero-lockfile" }} paths: - <> - when: condition: << parameters.with-cache >> steps: - when: condition: << parameters.cache-path >> steps: - save_cache: key: node-deps-{{ arch }}-<>-<<#parameters.include-branch-in-cache-key>>{{ .Branch }}-<><<^parameters.cache-only-lockfile>>{{ checksum "/tmp/node-project-package.json" }}-<>{{ checksum "/tmp/node-project-lockfile" }} paths: - <> - unless: condition: << parameters.cache-path >> steps: - save_cache: key: node-deps-{{ arch }}-<>-<<#parameters.include-branch-in-cache-key>>{{ .Branch }}-<><<^parameters.cache-only-lockfile>>{{ checksum "/tmp/node-project-package.json" }}-<>{{ checksum "/tmp/node-project-lockfile" }} paths: - ~/.yarn/berry/cache - <>/.yarn/cache - when: condition: equal: - bun - << parameters.pkg-manager >> steps: - run: command: | #!/usr/bin/env bash # Configure bun cache path if provided if [[ -n "$PARAM_CACHE_PATH" ]]; then export BUN_INSTALL_CACHE_DIR="$PARAM_CACHE_PATH" elif [[ -z "$BUN_INSTALL_CACHE_DIR" ]]; then # Set default cache directory to match what the orb caches export BUN_INSTALL_CACHE_DIR="$HOME/.bun/install/cache" fi # Run override ci command if provided, otherwise run default bun install # Note: bun install respects bunfig.toml configuration automatically if [[ -n "$PARAM_OVERRIDE_COMMAND" ]]; then echo "Running override package installation command:" eval "$PARAM_OVERRIDE_COMMAND" else bun install --frozen-lockfile fi environment: PARAM_CACHE_PATH: << parameters.cache-path >> PARAM_OVERRIDE_COMMAND: << parameters.override-ci-command >> name: Installing BUN packages working_directory: <> - when: condition: << parameters.with-cache >> steps: - when: condition: << parameters.cache-path >> steps: - save_cache: key: node-deps-{{ arch }}-<>-<<#parameters.include-branch-in-cache-key>>{{ .Branch }}-<><<^parameters.cache-only-lockfile>>{{ checksum "/tmp/node-project-package.json" }}-<>{{ checksum "/tmp/node-project-lockfile" }} paths: - <> - unless: condition: << parameters.cache-path >> steps: - save_cache: key: node-deps-{{ arch }}-<>-<<#parameters.include-branch-in-cache-key>>{{ .Branch }}-<><<^parameters.cache-only-lockfile>>{{ checksum "/tmp/node-project-package.json" }}-<>{{ checksum "/tmp/node-project-lockfile" }} paths: - ~/.bun/install/cache - when: condition: << parameters.with-cache >> steps: - run: command: rm -f /tmp/node-project-lockfile /tmp/node-project-package.json /tmp/yarn-zero-lockfile name: Remove temporary links install-pnpm: description: | Install a custom version of the pnpm package manager parameters: version: default: "" description: | Pick a version of pnpm to install (if no version is specified, the latest stable version will be installed): https://github.com/pnpm/pnpm/releases type: string steps: - run: command: | #!/usr/bin/env bash if [[ $EUID == 0 ]]; then export SUDO=""; else export SUDO="sudo"; fi # FUNCTIONS get_pnpm_version () { if [[ "$NODE_PARAM_PNPM_VERSION" == "" ]]; then PNPM_ORB_VERSION=$(curl -s https://cdn.jsdelivr.net/npm/pnpm/package.json | sed -n 's/.*version": "\(.*\)".*/\1/p') echo "Latest version of pnpm is $PNPM_ORB_VERSION" else PNPM_ORB_VERSION="$NODE_PARAM_PNPM_VERSION" echo "Selected version of pnpm is $PNPM_ORB_VERSION" fi } installation_check () { echo "Checking if pnpm is already installed..." if command -v pnpm > /dev/null 2>&1; then if pnpm --version | grep "$PNPM_ORB_VERSION" > /dev/null 2>&1; then echo "pnpm $PNPM_ORB_VERSION is already installed" exit 0 else echo "A different version of pnpm is installed ($(pnpm --version)); removing it" $SUDO rm -rf "$(pnpm store path)" > /dev/null 2>&1 $SUDO rm -rf "$PNPM_HOME" > /dev/null 2>&1 $SUDO npm rm -g pnpm > /dev/null 2>&1 fi fi } # cd to home so that pnpm --version will not use relative installed pnpm cd ~ || echo "Cannot change directory to home directory, pnpm version may be mismatched." get_pnpm_version installation_check # install pnpm echo "Installing pnpm v$PNPM_ORB_VERSION" if [ -w "$(npm root -g)" ]; then npm install -g "pnpm@$PNPM_ORB_VERSION" else $SUDO npm install -g "pnpm@$PNPM_ORB_VERSION" fi # test/verify version echo "Verifying pnpm install" if pnpm --version | grep "$PNPM_ORB_VERSION" > /dev/null 2>&1; then echo "Success! pnpm $(pnpm --version) has been installed to $(command -v pnpm)" else echo "Something went wrong; the specified version of pnpm could not be installed" exit 1 fi environment: NODE_PARAM_PNPM_VERSION: <> name: Install pnpm install-yarn: description: | Install a custom version of the Yarn package manager. This only works for yarn classic versions, if you want to use yarn-berry, use the install-packages directly and select yarn-berry as pkg-manager. parameters: version: default: "" description: | Pick a version of Yarn to install (if no version is specified, the latest stable version will be installed): https://github.com/yarnpkg/yarn/releases type: string steps: - run: command: | #!/usr/bin/env bash if [[ $EUID == 0 ]]; then export SUDO=""; else export SUDO="sudo"; fi # FUNCTIONS get_yarn_version () { if [[ "$NODE_PARAM_YARN_VERSION" == "" ]]; then YARN_ORB_VERSION=$(curl -s https://cdn.jsdelivr.net/npm/yarn/package.json | sed -n 's/.*version": "\(.*\)".*/\1/p') echo "Latest version of Yarn is $YARN_ORB_VERSION" else YARN_ORB_VERSION="$NODE_PARAM_YARN_VERSION" echo "Selected version of Yarn is $YARN_ORB_VERSION" fi } installation_check () { echo "Checking if YARN is already installed..." if command -v yarn > /dev/null 2>&1; then if yarn --version | grep "$YARN_ORB_VERSION" > /dev/null 2>&1; then echo "Yarn $YARN_ORB_VERSION is already installed" exit 0 else echo "A different version of Yarn is installed ($(yarn --version)); removing it" if uname -a | grep Darwin > /dev/null 2>&1; then brew uninstall yarn > /dev/null 2>&1 elif grep Alpine /etc/issue > /dev/null 2>&1; then apk del yarn > /dev/null 2>&1 elif grep Debian /etc/issue > /dev/null 2>&1; then $SUDO apt-get remove yarn > /dev/null 2>&1 && \ $SUDO apt-get purge yarn > /dev/null 2>&1 OLD_YARN=$(which yarn) $SUDO rm "$OLD_YARN" elif grep Ubuntu /etc/issue > /dev/null 2>&1; then $SUDO apt-get remove yarn > /dev/null 2>&1 && \ $SUDO apt-get purge yarn > /dev/null 2>&1 OLD_YARN=$(which yarn) $SUDO rm "$OLD_YARN" elif command -v yum > /dev/null 2>&1; then yum remove yarn > /dev/null 2>&1 fi $SUDO rm -rf "$HOME/.yarn" > /dev/null 2>&1 $SUDO rm -f /usr/local/bin/yarn /usr/local/bin/yarnpkg > /dev/null 2>&1 fi fi } # cd to home so that yarn --version will not use relative installed yarn from .yarn/releases cd ~ || echo "Cannot change directory to home directory, yarn version may be mismatched." get_yarn_version installation_check # install yarn echo "Installing YARN v$YARN_ORB_VERSION" curl --retry 5 -L -o yarn.tar.gz --silent "https://yarnpkg.com/downloads/$YARN_ORB_VERSION/yarn-v$YARN_ORB_VERSION.tar.gz" $SUDO tar -xzf yarn.tar.gz && rm yarn.tar.gz $SUDO mkdir -p /opt/yarn $SUDO mv yarn-v"${YARN_ORB_VERSION}"/* /opt/yarn $SUDO rm -rf "yarn-v${YARN_ORB_VERSION}" $SUDO chmod 777 "/opt/yarn" $SUDO ln -s /opt/yarn/bin/yarn /usr/local/bin/yarn $SUDO ln -s /opt/yarn/bin/yarnpkg /usr/local/bin/yarnpkg $SUDO ln -s /opt/yarn/bin/yarn.js /usr/local/bin/yarn.js $SUDO mkdir -p ~/.config if uname -a | grep Darwin; then $SUDO chown -R "$USER:$GROUP" ~/.config $SUDO chown -R "$USER:$GROUP" /opt/yarn else $SUDO chown -R "$(whoami):$(whoami)" /opt/yarn $SUDO chown -R "$(whoami):$(whoami)" ~/.config fi # test/verify version echo "Verifying YARN install" if yarn --version | grep "$YARN_ORB_VERSION" > /dev/null 2>&1; then echo "Success! Yarn $(yarn --version) has been installed to $(command -v yarn)" else echo "Something went wrong; the specified version of Yarn could not be installed" exit 1 fi environment: NODE_PARAM_YARN_VERSION: <> name: Install Yarn executors: default: description: | Select the version of Node.js to use. Uses CircleCI's highly cached convenience images built for CI. Any available tag from this list can be used: https://hub.docker.com/r/cimg/node/tags docker: - image: cimg/node:<> parameters: resource_class: default: large description: Configure the executor resource class enum: - small - medium - medium+ - large - xlarge - 2xlarge - 2xlarge+ - arm.medium - arm.large - arm.xlarge - arm.2xlarge type: enum tag: default: lts description: | Pick a specific cimg/node image version tag: https://hub.docker.com/r/cimg/node type: string resource_class: << parameters.resource_class >> jobs: run: description: | Simple drop-in job to run commands for your Node.js application automatically. executor: <> parallelism: <> parameters: app-dir: default: ~/project description: Path to the directory containing your package.json file. Not needed if package.json lives in the root. type: string artifacts-path: default: "" description: | Path to a file or directory to upload to artifacts after running the script. type: string bun-run: default: "" description: The name of the script within your package.json which you would like to run. type: string cache-only-lockfile: default: true description: | If true, package.json will be ignored in the cache key. Useful for projects where package.json changes do not always invalidate dependencies. Note: package.json will still be the final fallback key incase a project is not configured with a lock file. type: boolean cache-path: default: "" description: | By default, this orb will utilize 'npm ci' and cache the '~/.npm' directory. Override which path to cache with this parameter. The cache will be ignored when using npm ci, as the command doesn't benefit from cache. type: string cache-version: default: v1 description: Change the default cache version if you need to clear the cache for any reason. type: string check-cache: default: never description: | Yarn berry only for Zero install support - Use 'always' to always --check-cache argument to yarn install. Use 'detect' to enable caching of yarn.lock and to only add when required. enum: - never - always - detect type: enum executor: default: default description: The name of executor to use. type: executor include-branch-in-cache-key: default: false description: | If true, this cache bucket will only apply to jobs within the same branch. type: boolean npm-run: default: "" description: The name of the script within your package.json which you would like to run. type: string override-ci-command: default: "" description: | By default, packages will be installed with "npm ci" or "yarn install --frozen-lockfile". Optionally supply a custom package installation command, with any additional flags needed. type: string parallelism: default: 1 description: The number of parallel jobs to run. See https://circleci.com/docs/parallelism-faster-jobs/ type: integer pkg-manager: default: npm description: Select the default node package manager to use. enum: - npm - yarn - yarn-berry - pnpm - bun type: enum pnpm-run: default: "" description: The name of the script within your package.json which you would like to run. type: string post_install_steps: default: [] description: Provide any optional steps you would like to run after installing the node dependencies. type: steps setup: default: [] description: Provide any optional steps you would like to run prior to installing the node dependencies. This is a good place to install global modules. type: steps with-cache: default: true description: | Cache your node packages automatically for faster install times. Cache will be ignored when using npm ci. type: boolean yarn-run: default: "" description: The name of the script within your package.json which you would like to run. type: string steps: - checkout - steps: << parameters.setup >> - install-packages: app-dir: <> cache-only-lockfile: <> cache-path: <> cache-version: <> check-cache: <> include-branch-in-cache-key: <> override-ci-command: <> pkg-manager: <> with-cache: <> - steps: << parameters.post_install_steps >> - run: command: | #!/usr/bin/env bash if [[ "$ORB_PARAM_PKG_MANAGER" == "npm" ]]; then npm run "$ORB_PARAM_NPM_RUN" elif [[ "$ORB_PARAM_PKG_MANAGER" == "pnpm" ]]; then pnpm run "$ORB_PARAM_PNPM_RUN" elif [[ "$ORB_PARAM_PKG_MANAGER" == "bun" ]]; then bun run "$ORB_PARAM_BUN_RUN" else yarn run "$ORB_PARAM_YARN_RUN" fi environment: ORB_PARAM_BUN_RUN: <> ORB_PARAM_NPM_RUN: <> ORB_PARAM_PKG_MANAGER: <> ORB_PARAM_PNPM_RUN: <> ORB_PARAM_YARN_RUN: <> name: Run <> <> working_directory: <> - when: condition: <> steps: - store_artifacts: path: <> test: description: | Simple drop-in job to test your Node.js application automatically. executor: <> parallelism: <> parameters: app-dir: default: ~/project description: Path to the directory containing your package.json file. Not needed if package.json lives in the root. type: string cache-only-lockfile: default: true description: | If true, package.json will be ignored in the cache key. Useful for projects where package.json changes do not always invalidate dependencies. Note: package.json will still be the final fallback key incase a project is not configured with a lock file. type: boolean cache-path: default: "" description: | By default, this orb will utilize 'npm ci' and cache the '~/.npm' directory. Override which path to cache with this parameter. The cache will be ignored when using npm ci, as the command doesn't benefit from cache. type: string cache-version: default: v1 description: Change the default cache version if you need to clear the cache for any reason. type: string check-cache: default: never description: | Yarn berry only for Zero install support - Use 'always' to always --check-cache argument to yarn install. Use 'detect' to enable caching of yarn.lock and to only add when required. enum: - never - always - detect type: enum executor: default: default description: The name of executor to use. type: executor include-branch-in-cache-key: default: false description: | If true, this cache bucket will only apply to jobs within the same branch. type: boolean override-ci-command: default: "" description: | By default, packages will be installed with "npm ci" or "yarn install --frozen-lockfile". Optionally supply a custom package installation command, with any additional flags needed. type: string parallelism: default: 1 description: The number of parallel jobs to run. See https://circleci.com/docs/parallelism-faster-jobs/ type: integer pkg-manager: default: npm description: Select the default node package manager to use. enum: - npm - yarn - yarn-berry - pnpm - bun type: enum post_install_steps: default: [] description: Provide any optional steps you would like to run after installing the node dependencies. type: steps run-command: default: test description: The name of the script within your package.json which will run your tests. type: string setup: default: [] description: Provide any optional steps you would like to run prior to installing the node dependencies. This is a good place to install global modules. type: steps test-coverage-path: default: "" description: | Set this to the location where code coverage files will be placed after running tests. The code coverage files will be uploaded to artifacts for this workflow. type: string test-results-for: default: other description: | Testing framework your project uses. If this is set to jest or mocha, test results will be automatically produced. When using jest, the jest-junit package is required as a dev dependency. See https://github.com/jest-community/jest-junit for more information. When using mocha, the mocha-junit-reporter and mocha-multi packages are required as dev dependency. See https://github.com/michaelleeallen/mocha-junit-reporter and https://github.com/glenjamin/mocha-multi for more information. When using bun with pkg-manager: bun, Bun's native test runner will be used with built-in JUnit output. enum: - jest - mocha - bun - other type: enum test-results-path: default: "" description: | If you use test-results-for, this will be configured automatically. If you configure test results yourself (for example in your node config files) set this to the location that you write them to, and they will be uploaded. type: string with-cache: default: true description: | Cache your node packages automatically for faster install times. Cache will be ignored when using npm ci. type: boolean steps: - checkout - steps: << parameters.setup >> - install-packages: app-dir: <> cache-only-lockfile: <> cache-path: <> cache-version: <> check-cache: <> include-branch-in-cache-key: <> override-ci-command: <> pkg-manager: <> with-cache: <> - steps: << parameters.post_install_steps >> - when: condition: and: - equal: - npm - << parameters.pkg-manager >> - equal: - other - << parameters.test-results-for >> steps: - run: command: npm run <> name: Run NPM Tests working_directory: <> - when: condition: and: - equal: - npm - << parameters.pkg-manager >> - equal: - jest - << parameters.test-results-for >> steps: - run: command: npm list jest-junit || (echo "Add the package jest-junit to the dev dependencies of your project with `npm install --save-dev jest-junit`" && exit 1) name: Check for test reporter working_directory: <> - run: command: npm run <> -- --reporters=default --reporters=jest-junit name: Run NPM Tests working_directory: <> - when: condition: and: - equal: - npm - << parameters.pkg-manager >> - equal: - mocha - << parameters.test-results-for >> steps: - run: command: npm list mocha-junit-reporter mocha-multi || (echo "Add the packages mocha-junit-reporter & mocha-multi to the dev dependencies of your project with `npm install --save-dev mocha-junit-reporter mocha-multi`" && exit 1) name: Check for test reporter working_directory: <> - run: command: npm run <> -- --reporter mocha-multi --reporter-options spec=-,mocha-junit-reporter=- name: Run NPM Tests working_directory: <> - when: condition: and: - equal: - yarn - << parameters.pkg-manager >> - equal: - other - << parameters.test-results-for >> steps: - run: command: yarn run <> name: Run YARN Tests working_directory: <> - when: condition: and: - equal: - yarn - << parameters.pkg-manager >> - equal: - jest - << parameters.test-results-for >> steps: - run: command: | #!/usr/bin/env bash set -x YARN_VERSION=$(yarn --version) MAJOR_VERSION=${YARN_VERSION%%.*} if [[ "$MAJOR_VERSION" -eq 1 ]]; then yarn list --pattern "${PARAM_PATTERN}" | grep "${PARAM_GREP}" || (echo "${PARAM_ERROR}" && exit 1) else yarn info | grep "${PARAM_GREP}" || (echo "${PARAM_ERROR}" && exit 1) fi environment: PARAM_ERROR: Add the package jest-junit to your projects dev dependencies with `yarn add --dev jest-junit` PARAM_GREP: ' jest-junit@' PARAM_PATTERN: jest-junit name: Check for test reporter working_directory: <> - run: command: yarn run <> --reporters=default --reporters=jest-junit name: Run YARN Tests working_directory: <> - when: condition: and: - equal: - yarn - << parameters.pkg-manager >> - equal: - mocha - << parameters.test-results-for >> steps: - run: command: | #!/usr/bin/env bash set -x YARN_VERSION=$(yarn --version) MAJOR_VERSION=${YARN_VERSION%%.*} if [[ "$MAJOR_VERSION" -eq 1 ]]; then yarn list --pattern "${PARAM_PATTERN}" | grep "${PARAM_GREP}" || (echo "${PARAM_ERROR}" && exit 1) else yarn info | grep "${PARAM_GREP}" || (echo "${PARAM_ERROR}" && exit 1) fi environment: PARAM_ERROR: Add the packages mocha-junit-reporter & mocha-multi to the dev dependencies of your project with `yarn add --dev mocha-junit-reporter mocha-multi` PARAM_GREP: mocha-junit-reporter@\|mocha-multi@ PARAM_PATTERN: mocha-junit-reporter|mocha-multi name: Check for test reporter working_directory: <> - run: command: yarn run <> --reporter mocha-multi --reporter-options spec=-,mocha-junit-reporter=- name: Run YARN Tests working_directory: <> - when: condition: and: - equal: - yarn-berry - << parameters.pkg-manager >> - equal: - other - << parameters.test-results-for >> steps: - run: command: yarn run <> name: Run YARN 2.x Tests working_directory: <> - when: condition: and: - equal: - yarn-berry - << parameters.pkg-manager >> - equal: - jest - << parameters.test-results-for >> steps: - run: command: yarn run <> --reporters=default --reporters=jest-junit name: Run YARN 2.x Tests working_directory: <> - when: condition: and: - equal: - yarn-berry - << parameters.pkg-manager >> - equal: - mocha - << parameters.test-results-for >> steps: - run: command: | #!/usr/bin/env bash set -x YARN_VERSION=$(yarn --version) MAJOR_VERSION=${YARN_VERSION%%.*} if [[ "$MAJOR_VERSION" -eq 1 ]]; then yarn list --pattern "${PARAM_PATTERN}" | grep "${PARAM_GREP}" || (echo "${PARAM_ERROR}" && exit 1) else yarn info | grep "${PARAM_GREP}" || (echo "${PARAM_ERROR}" && exit 1) fi environment: PARAM_ERROR: Add the packages mocha-junit-reporter & mocha-multi to the dev dependencies of your project with `yarn add --dev mocha-junit-reporter mocha-multi` PARAM_GREP: mocha-junit-reporter@\|mocha-multi@ PARAM_PATTERN: mocha-junit-reporter|mocha-multi name: Check for test reporter working_directory: <> - run: command: yarn run <> --reporter mocha-multi --reporter-options spec=-,mocha-junit-reporter=- name: Run YARN 2.x Tests working_directory: <> - when: condition: and: - equal: - pnpm - << parameters.pkg-manager >> - equal: - other - << parameters.test-results-for >> steps: - run: command: pnpm run <> name: Run pnpm Tests working_directory: <> - when: condition: and: - equal: - pnpm - << parameters.pkg-manager >> - equal: - jest - << parameters.test-results-for >> steps: - run: command: pnpm list "jest-junit@*" | grep "jest-junit" || (echo "Add the package jest-junit to your projects dev dependencies with `pnpm add -D jest-junit`" && exit 1) name: Check for test reporter working_directory: <> - run: command: pnpm run <> --reporters=default --reporters=jest-junit name: Run pnpm Tests working_directory: <> - when: condition: and: - equal: - pnpm - << parameters.pkg-manager >> - equal: - mocha - << parameters.test-results-for >> steps: - run: command: pnpm list "mocha-junit-reporter@*" "mocha-multi@*" | grep "mocha-junit-reporter\|mocha-multi" || (echo "Add the packages mocha-junit-reporter & mocha-multi to the dev dependencies of your project with `pnpm add -D mocha-junit-reporter mocha-multi`" && exit 1) name: Check for test reporter working_directory: <> - run: command: pnpm run <> --reporter mocha-multi --reporter-options spec=-,mocha-junit-reporter=- name: Run pnpm Tests working_directory: <> - when: condition: and: - equal: - bun - << parameters.pkg-manager >> - equal: - other - << parameters.test-results-for >> steps: - run: command: bun run <> name: Run Bun Tests working_directory: <> - when: condition: and: - equal: - bun - << parameters.pkg-manager >> - equal: - jest - << parameters.test-results-for >> steps: - run: command: bun pm ls | grep "jest-junit" || (echo "Add the package jest-junit to your projects dev dependencies with \`bun add -D jest-junit\`" && exit 1) name: Check for test reporter working_directory: <> - run: command: bun run <> --reporters=default --reporters=jest-junit --modulePathIgnorePatterns='/\.bun/' --modulePathIgnorePatterns='\.bun/' name: Run Bun Tests working_directory: <> - when: condition: and: - equal: - bun - << parameters.pkg-manager >> - equal: - mocha - << parameters.test-results-for >> steps: - run: command: bun pm ls | grep -E "mocha-junit-reporter|mocha-multi" || (echo "Add the packages mocha-junit-reporter & mocha-multi to the dev dependencies of your project with \`bun add -D mocha-junit-reporter mocha-multi\`" && exit 1) name: Check for test reporter working_directory: <> - run: command: bun run <> --reporter mocha-multi --reporter-options spec=-,mocha-junit-reporter=- name: Run Bun Tests working_directory: <> - when: condition: and: - equal: - bun - << parameters.pkg-manager >> - equal: - bun - << parameters.test-results-for >> steps: - run: command: mkdir -p ./test-results/bun && bun test bun-tests --reporter=junit --reporter-outfile=./test-results/bun/results.xml name: Run Bun Native Tests with JUnit output working_directory: <> - when: condition: << parameters.test-results-path >> steps: - store_test_results: path: << parameters.test-results-path >> - when: condition: and: - equal: - jest - << parameters.test-results-for >> - equal: - "" - << parameters.test-results-path >> steps: - store_test_results: path: <>/junit.xml - when: condition: and: - equal: - mocha - << parameters.test-results-for >> - equal: - "" - << parameters.test-results-path >> steps: - store_test_results: path: <>/test-results.xml - when: condition: and: - equal: - bun - << parameters.pkg-manager >> - equal: - jest - << parameters.test-results-for >> - equal: - "" - << parameters.test-results-path >> steps: - store_test_results: path: <>/test-results - when: condition: and: - equal: - bun - << parameters.pkg-manager >> - equal: - bun - << parameters.test-results-for >> - equal: - "" - << parameters.test-results-path >> steps: - store_test_results: path: <>/test-results/bun - when: condition: <> steps: - store_artifacts: path: <> examples: bun_install: description: | By default, the "install-packages" command will attempt to utilize "bun install". The command can however be overwritten to support an alternative package install command such as "bun install --frozen-lockfile". usage: version: "2.1" orbs: node: circleci/node@x.y jobs: test: executor: node/default steps: - checkout - node/install-bun: version: 1.2.22 - node/install-packages: pkg-manager: bun - run: bun run test workflows: test_my_app: jobs: - test install_nodejs: description: | Download and install any version of Node.js. Optionally installs Yarn with a parameter. You may use the default executor of this orb for a Node execution environment as well. Recommendation: It is highly recommended to utilize an environment such as Docker with Node preinstalled. usage: version: "2.1" orbs: node: circleci/node@x.y jobs: install-node-example: docker: - image: cimg/base:stable steps: - checkout - node/install: install-yarn: true node-version: "16.13" - run: node --version workflows: test_my_app: jobs: - install-node-example jest_test_results: description: | Run tests with jest and produce and upload test reports. This assumes that you have configured your project to invoke jest as your test script and that you have the jest-junit package in your dev dependencies. usage: version: "2.1" orbs: node: circleci/node@x.y workflows: test: jobs: - node/test: test-results-for: jest mocha_test_results: description: | Run tests with mocha and produce and upload test reports. This assumes that you have configured your project to invoke mocha as your test script and that you have the mocha-junit-reporter and mocha-multi packages in your dev dependencies. usage: version: "2.1" orbs: node: circleci/node@x.y workflows: test: jobs: - node/test: executor: name: node/default test-results-for: mocha node_bun_run: description: | Drop-in solution to automatically run custom bun commands for your Node.js applications. This job will automatically download your code into any version node environment, install your dependencies with caching enabled, and execute your custom bun script. usage: version: "2.1" orbs: node: circleci/node@x.y workflows: run-bun-command: jobs: - node/run: bun-run: build executor: name: node/default pkg-manager: bun setup: - node/install-bun node_npm_run: description: | Drop-in solution to automatically run custom npm commands for your Node.js applications. This job will automatically download your code into any version node environment, install your dependencies with caching enabled, and execute your custom npm script. usage: version: "2.1" orbs: node: circleci/node@x.y workflows: run-npm-command: jobs: - node/run: executor: name: node/default npm-run: build node_pnpm_run: description: | Drop-in solution to automatically run custom pnpm commands for your Node.js applications. This job will automatically download your code into any version node environment, install your dependencies with caching enabled, and execute your custom pnpm script. usage: version: "2.1" orbs: node: circleci/node@x.y workflows: run-npm-command: jobs: - node/run: executor: name: node/default pnpm-run: build node_test_and_deploy: description: | Drop-in solution to automatically test your Node.js applications. This job will automatically download your code into any version node environment, install your dependencies with caching enabled, and execute your testing script. This example shows how easily with two orbs you can test your Node application and automatically deploy to Heroku when successful, and on the master branch. usage: version: "2.1" orbs: heroku: circleci/heroku@x.y node: circleci/node@x.y workflows: test-and-deploy: jobs: - node/test: executor: name: node/default - heroku/deploy-via-git: filters: branches: only: - master requires: - node/test node_yarn_run: description: | Drop-in solution to automatically run custom yarn commands for your Node.js applications. This job will automatically download your code into any version node environment, install your dependencies with caching enabled, and execute your custom yarn script. usage: version: "2.1" orbs: node: circleci/node@x.y workflows: run-npm-command: jobs: - node/run: executor: name: node/default yarn-run: build npm_install: description: | By default, the "install-packages" command will attempt to utilize "npm ci". The command can however be overwritten to support an alternative package install command such as "npm install". usage: version: "2.1" orbs: node: circleci/node@x.y jobs: test: executor: node/default steps: - checkout - run: sudo npm install -g npm@latest - node/install-packages: cache-path: ~/project/node_modules override-ci-command: npm install - run: npm run test workflows: test_my_app: jobs: - test pnpm_install: description: | By default, the "install-packages" command will attempt to utilize "pnpm i --frozen-lockfile". The command can however be overwritten to support an alternative package install command such as "pnpm install". usage: version: "2.1" orbs: node: circleci/node@x.y jobs: test: executor: node/default steps: - checkout - run: sudo npm install -g npm@latest - node/install-packages: override-ci-command: pnpm i pkg-manager: pnpm - run: pnpm run test workflows: test_my_app: jobs: - test run_matrix_testing: description: | Easily test your application against multiple versions of Node.js in just a few lines. This example uses "Matrix" jobs to call the same node/test job multiple times at once, each with the Node version we have specified. Read more here: https://circleci.com/blog/you-are-what-you-git-how-your-vcs-branching-model-affects-your-delivery-cadence/ usage: version: "2.1" orbs: node: circleci/node@x.y workflows: matrix-tests: jobs: - node/test: matrix: parameters: executor: - node13 - node12 - node10 run_tests_with_bun: description: | Manual approach for running Bun's native test runner. This example shows how to manually configure Bun tests with JUnit output. For automatic test result collection, consider using the node/test job with test-results-for: bun (see test_with_bun_native.yml example). The "bun install" command will automatically be applied and Bun's cache directory will be cached. usage: version: "2.1" orbs: node: circleci/node@x.y jobs: test: executor: name: node/default tag: 22.19.0 steps: - checkout - node/install-bun: version: 1.2.22 - node/install-packages: pkg-manager: bun - run: command: bun test name: Run Bun tests - run: command: bun test --reporter junit --bail name: Run Bun tests with JUnit output when: always - store_test_results: path: ./junit.xml workflows: test_my_app: jobs: - test run_tests_with_npm: description: | How to quickly and easily run your Node.js tests on CircleCI with caching automatically included. This example assumes you are using NPM as your package manager. The "npm ci" command will automatically be applied and the "~/.npm" directory cached. usage: version: "2.1" orbs: node: circleci/node@x.y jobs: test: executor: name: node/default tag: "13.14" steps: - checkout - node/install-packages - run: command: npm run test workflows: test_my_app: jobs: - test run_tests_with_pnpm: description: | Utilize the pnpm package manager with the CircleCI Node orb. Caching of your Node packages is enabled by default. usage: version: "2.1" orbs: node: circleci/node@x.y jobs: test: executor: name: node/default tag: "16" steps: - checkout - node/install-packages: pkg-manager: pnpm - run: command: pnpm run test name: Run pnpm tests workflows: test_my_app: jobs: - test run_tests_with_yarn: description: | Utilize the YARN package manager with the CircleCI Node orb. Caching of your Node packages is enabled by default. usage: version: "2.1" orbs: node: circleci/node@x.y jobs: test: executor: name: node/default tag: "16" steps: - checkout - node/install-packages: pkg-manager: yarn - run: command: yarn run test name: Run YARN tests workflows: test_my_app: jobs: - test test_results: description: | Run tests with jest and produce and upload test reports. This assumes that you have configured your project so that your test script will produce the junit.xml file. usage: version: "2.1" orbs: node: circleci/node@x.y workflows: test: jobs: - node/test: executor: name: node/default test-results-path: junit.xml test_with_bun_native: description: | Use the test job with Bun's native test runner for automatic test result collection. When using "test-results-for: bun" with "pkg-manager: bun", the orb will automatically: - Run Bun's built-in test runner with JUnit output - Collect and store test results for CircleCI's test summary Note: This is different from "test-results-for: jest" which runs Jest with Bun acting as a script runner. usage: version: "2.1" orbs: node: circleci/node@x.y workflows: test_my_app: jobs: - node/test: name: test-with-bun-native pkg-manager: bun setup: - node/install-bun: version: 1.2.22 test-results-for: bun - node/test: name: test-with-jest-via-bun pkg-manager: bun run-command: test:jest setup: - node/install-bun: version: 1.2.22 test-results-for: jest yarn_berry_zero_install: description: | Utilize the YARN v2 package manager + Zero installs with the CircleCI Node orb. usage: version: "2.1" orbs: node: circleci/node@x.y jobs: test: executor: name: node/default tag: "16" steps: - checkout - node/install-packages: check-cache: always pkg-manager: yarn-berry with-cache: false - run: command: yarn run test name: Run YARN tests workflows: test_my_app: jobs: - test orb-tools: circleci/orb-tools@12.0 jq: circleci/jq@3.0 filters: &filters tags: only: /.*/ release-filters: &release-filters branches: ignore: /.*/ tags: only: /^v[0-9]+\.[0-9]+\.[0-9]+$/ executors: linux: docker: - image: cimg/base:stable macos: macos: xcode: 16.3.0 machine: machine: image: ubuntu-2004:current windows: machine: image: windows-server-2022-gui:current shell: bash.exe resource_class: windows.medium jobs: # Install Node.js into a non-node container. integration-test-install-specified-version: parameters: os: type: executor executor: <> steps: - checkout - node/install: node-version: "16.13" install-yarn: true # Test the install of YARN yarn-version: "1.22.5" nvm-cache-key: v2 - run: command: | if ! node --version | grep -q "16"; then echo "Node version 16 not found" exit 1 fi integration-test-install-pnpm: parameters: os: type: executor executor: <> steps: - checkout - node/install: install-pnpm: true # Test the install of PNPM pnpm-version: "9.7.1" nvm-cache-key: v2-{{ arch }} - run: command: | if ! pnpm --version | grep -q "9.7.1"; then echo "pnpm version 9.7.1 not found" exit 1 fi integration-test-install-bun-specified: parameters: os: type: executor executor: <> steps: - checkout - node/install: nvm-cache-key: v2 - node/install-bun: version: "1.2.22" - run: command: | if ! bun --version | grep -q "1.2.22"; then echo "Bun version 1.2.22 not found" exit 1 fi integration-test-reinstall-yarn: machine: image: ubuntu-2004:current steps: - node/install-yarn integration-test-install-latest: parameters: os: type: executor executor: <> steps: - checkout - node/install: node-version: "latest" nvm-cache-key: v2 - run: name: Check that latest Node.js is installed. command: | NODE_ORB_INSTALL_VERSION=$(nvm ls-remote | tail -n1 | grep -Eo 'v[0-9]+\.[0-9]+\.[0-9]+') echo "Latest Node version = $NODE_ORB_INSTALL_VERSION" echo "Installed version: $(node --version)" if ! node --version | grep -q "$NODE_ORB_INSTALL_VERSION"; then echo "Error: Installed version is different from the latest version." exit 1 fi integration-test-override-yarn: docker: - image: cimg/ruby:3.3.5-browsers steps: - node/install: install-yarn: true node-version: '22.11.0' integration-test-use-nvmrc-version: parameters: os: type: executor executor: <> steps: - checkout - run: echo '16.13' > .nvmrc - node/install integration-test-use-node-version-version: parameters: os: type: executor executor: <> steps: - checkout - run: echo '16.13' > .node-version - node/install integration-test-install-lts: parameters: os: type: executor executor: <> steps: - checkout - node/install - run: name: Check that the latest LTS version of Node.js is installed. command: | NODE_ORB_INSTALL_VERSION=$(nvm ls-remote | grep 'Latest LTS' | grep -Eo 'v[0-9]+\.[0-9]+\.[0-9]+') echo "Latest Node LTS version = $NODE_ORB_INSTALL_VERSION" echo "Installed version: $(node --version)" if ! node --version | grep -q "$NODE_ORB_INSTALL_VERSION"; then echo "Error: Installed version is different from the latest LTS version." exit 1 fi integration-test-override-ci: parameters: resource_class: type: enum default: medium description: Configure the executor resource class enum: - medium - arm.medium executor: name: node/default resource_class: <> steps: - checkout - node/install-packages: override-ci-command: npm install cache-path: ~/project/node_modules cache-version: override-v3 app-dir: "~/project/sample" - run: cd ~/project/sample && npm run test integration-test-override-ci-windows: executor: windows steps: - checkout - run: name: Install Node.js command: | nvm install lts nvm use lts - node/install-packages: override-ci-command: npm install cache-path: ~/project/node_modules cache-version: override-v3 app-dir: "~/project/sample" - run: cd ~/project/sample && npm run test integration-test-pnpm: parameters: resource_class: type: enum default: medium description: Configure the executor resource class enum: - medium - arm.medium executor: name: node/default resource_class: <> steps: - checkout - run: name: Remove other lock files command: | rm ~/project/sample/package-lock.json rm ~/project/sample/yarn.lock rm ~/project/sample/bun.lock - node/install-pnpm: version: "9.12.3" - node/install-packages: pkg-manager: pnpm cache-version: pnpm-v1 app-dir: "~/project/sample" - run: cd ~/project/sample && pnpm test integration-test-bun: parameters: resource_class: type: enum default: medium description: Configure the executor resource class enum: - medium - arm.medium executor: name: node/default resource_class: <> steps: - checkout - run: name: Remove other lock files and create bun lockfile command: | rm ~/project/sample/package-lock.json rm ~/project/sample/yarn.lock rm ~/project/sample/pnpm-lock.yaml rm ~/project/sample/yarn-berry.lock - node/install-bun: version: "1.2.22" - node/install-packages: pkg-manager: bun cache-path: ~/.bun/install/cache cache-version: bun-v1 app-dir: "~/project/sample" - run: cd ~/project/sample && bun test integration-test-yarn: parameters: resource_class: type: enum default: medium description: Configure the executor resource class enum: - medium - arm.medium executor: name: node/default resource_class: <> steps: - checkout - node/install-packages: pkg-manager: yarn cache-version: yarn-v3 app-dir: "~/project/sample" - run: yarn --version - run: cd ~/project/sample && yarn test integration-test-yarn-berry-nocimg: environment: YARN_ENABLE_IMMUTABLE_INSTALLS: false docker: - image: cypress/browsers steps: - checkout - run: mv ~/project/sample/package-berry.json ~/project/sample/package.json - node/install-packages: pkg-manager: yarn-berry cache-version: yarn-berry-v2 app-dir: "~/project/sample" override-ci-command: yarn install - run: cd ~/project/sample && yarn test integration-test-yarn-berry: environment: YARN_ENABLE_IMMUTABLE_INSTALLS: false parameters: resource_class: type: enum default: medium description: Configure the executor resource class enum: - medium - arm.medium executor: name: node/default resource_class: <> steps: - checkout - run: mv ~/project/sample/package-berry.json ~/project/sample/package.json - node/install-packages: pkg-manager: yarn-berry cache-version: yarn-berry-v2 app-dir: "~/project/sample" override-ci-command: yarn install - run: cd ~/project/sample && yarn test workflows: test-deploy: jobs: - integration-test-override-yarn: filters: *filters - integration-test-reinstall-yarn: filters: *filters - integration-test-install-specified-version: filters: *filters matrix: parameters: os: [linux, macos, machine] - integration-test-install-pnpm: filters: *filters matrix: parameters: os: [linux, macos, machine] - integration-test-install-bun-specified: filters: *filters matrix: parameters: os: [linux, macos, machine] - integration-test-install-latest: filters: *filters matrix: parameters: os: [linux, macos, machine] - integration-test-install-lts: filters: *filters matrix: parameters: os: [linux, macos, machine] - node/test: filters: *filters name: node-npm-jest-test-job app-dir: "~/project/sample" cache-version: v2 test-results-for: jest setup: - run: name: Remove other lock files command: | rm ~/project/sample/pnpm-lock.yaml rm ~/project/sample/yarn.lock rm ~/project/sample/yarn-berry.lock rm ~/project/sample/bun.lock - node/test: filters: *filters name: node-yarn-jest-test-job app-dir: "~/project/sample" cache-version: v2 test-results-for: jest pkg-manager: yarn setup: - run: name: Remove other lock files command: | rm ~/project/sample/package-lock.json rm ~/project/sample/pnpm-lock.yaml rm ~/project/sample/yarn-berry.lock rm ~/project/sample/bun.lock - node/test: filters: *filters name: node-pnpm-jest-test-job app-dir: "~/project/sample" cache-version: v2 test-results-for: jest pkg-manager: pnpm setup: - run: name: Remove other lock files command: | rm ~/project/sample/package-lock.json rm ~/project/sample/yarn.lock rm ~/project/sample/yarn-berry.lock rm ~/project/sample/bun.lock - node/test: filters: *filters name: node-npm-mocha-test-job app-dir: "~/project/sample" cache-version: v2 test-results-for: mocha run-command: testmocha setup: - run: name: Remove other lock files command: | rm ~/project/sample/pnpm-lock.yaml rm ~/project/sample/yarn.lock rm ~/project/sample/yarn-berry.lock rm ~/project/sample/bun.lock - node/test: filters: *filters name: node-yarn-mocha-test-job app-dir: "~/project/sample" cache-version: v2 test-results-for: mocha pkg-manager: yarn run-command: testmocha setup: - run: name: Remove other lock files command: | rm ~/project/sample/package-lock.json rm ~/project/sample/pnpm-lock.yaml rm ~/project/sample/yarn-berry.lock rm ~/project/sample/bun.lock - node/test: filters: *filters name: node-yarn-berry-mocha-test-job app-dir: "~/project/sample" cache-version: v2-berry test-results-for: mocha pkg-manager: yarn-berry run-command: testmocha setup: - run: name: Remove other lock files command: | rm ~/project/sample/package-lock.json rm ~/project/sample/pnpm-lock.yaml rm ~/project/sample/yarn.lock rm ~/project/sample/bun.lock rm ~/project/sample/package.json mv ~/project/sample/yarn-berry.lock ~/project/sample/yarn.lock mv ~/project/sample/package-berry.json ~/project/sample/package.json - node/test: filters: *filters name: node-pnpm-mocha-test-job app-dir: "~/project/sample" cache-version: v2 test-results-for: mocha pkg-manager: pnpm run-command: testmocha setup: - run: name: Remove other lock files command: | rm ~/project/sample/package-lock.json rm ~/project/sample/yarn.lock rm ~/project/sample/yarn-berry.lock rm ~/project/sample/bun.lock - node/test: filters: *filters name: node-bun-jest-test-job app-dir: "~/project/sample" cache-version: v2 test-results-for: jest pkg-manager: bun cache-path: ~/.bun/install/cache setup: - node/install-bun: version: "1.2.22" - run: name: Remove other lock files command: | rm ~/project/sample/package-lock.json rm ~/project/sample/yarn.lock rm ~/project/sample/pnpm-lock.yaml rm ~/project/sample/yarn-berry.lock - node/test: filters: *filters name: node-bun-mocha-test-job app-dir: "~/project/sample" cache-version: v2 test-results-for: mocha pkg-manager: bun cache-path: ~/.bun/install/cache run-command: testmocha setup: - node/install-bun: version: "1.2.22" - run: name: Remove other lock files command: | rm ~/project/sample/package-lock.json rm ~/project/sample/yarn.lock rm ~/project/sample/pnpm-lock.yaml rm ~/project/sample/yarn-berry.lock - node/test: filters: *filters name: node-bun-native-test-job app-dir: "~/project/sample" cache-version: v2 test-results-for: bun pkg-manager: bun cache-path: ~/.bun/install/cache setup: - node/install-bun: version: "1.2.22" - run: name: Remove other lock files command: | rm ~/project/sample/package-lock.json rm ~/project/sample/yarn.lock rm ~/project/sample/pnpm-lock.yaml rm ~/project/sample/yarn-berry.lock post_install_steps: - run: name: Verify test results file was created command: | if [ -f ~/project/sample/test-results/bun/results.xml ] && [ -s ~/project/sample/test-results/bun/results.xml ]; then echo "Test results file created successfully at ~/project/sample/test-results/bun/results.xml" echo "File size: $(stat -f%z ~/project/sample/test-results/bun/results.xml 2>/dev/null || stat -c%s ~/project/sample/test-results/bun/results.xml) bytes" else echo "ERROR: Test results file not found or is empty" ls -la ~/project/sample/test-results/ 2>/dev/null || echo "test-results directory doesn't exist" exit 1 fi - node/test: filters: *filters name: node-yarn-mocha-with-test-result-path-job app-dir: "~/project/sample" cache-version: v2 test-results-for: mocha pkg-manager: yarn run-command: testmocha test-results-path: sample/test-results.xml setup: - run: name: Remove other lock files command: | rm ~/project/sample/package-lock.json rm ~/project/sample/pnpm-lock.yaml rm ~/project/sample/yarn-berry.lock rm ~/project/sample/bun.lock - node/test: filters: *filters name: node-test-results-file-job app-dir: "~/project/sample" cache-version: v2 test-results-path: sample/other-junit.xml setup: - run: name: Remove other lock files command: | rm ~/project/sample/pnpm-lock.yaml rm ~/project/sample/yarn.lock rm ~/project/sample/yarn-berry.lock rm ~/project/sample/bun.lock - node/test: filters: *filters name: node-test-no-junit app-dir: "~/project/sample" cache-version: v2 setup: - run: name: Remove other lock files command: | rm ~/project/sample/pnpm-lock.yaml rm ~/project/sample/yarn.lock rm ~/project/sample/yarn-berry.lock rm ~/project/sample/bun.lock - node/test: filters: *filters name: node-test-no-junit-new-features app-dir: "~/project/sample" cache-version: v2 executor: machine parallelism: 4 post_install_steps: - run: | echo "Packages installed" setup: - run: name: Remove other lock files command: | rm ~/project/sample/pnpm-lock.yaml rm ~/project/sample/yarn.lock rm ~/project/sample/yarn-berry.lock rm ~/project/sample/bun.lock - node/test: filters: *filters name: node-test-with-coverage app-dir: "~/project/sample" cache-version: v2 run-command: "test:coverage" test-coverage-path: ~/project/sample/coverage - node/run: filters: *filters name: node-run-npm-job app-dir: "~/project/sample" cache-version: v2 npm-run: build setup: - run: name: Remove other lock files command: | rm ~/project/sample/pnpm-lock.yaml rm ~/project/sample/yarn.lock rm ~/project/sample/yarn-berry.lock rm ~/project/sample/bun.lock - node/run: filters: *filters name: node-run-yarn-job app-dir: "~/project/sample" cache-version: v6 pkg-manager: yarn yarn-run: build setup: - run: name: Remove other lock files command: | rm ~/project/sample/package-lock.json rm ~/project/sample/pnpm-lock.yaml rm ~/project/sample/yarn-berry.lock rm ~/project/sample/bun.lock - node/run: filters: *filters name: node-run-upload-artifacts app-dir: "~/project/sample" cache-version: v2 npm-run: build artifacts-path: "~/project/sample/dist" - node/run: filters: *filters name: node-run-pnpm-job app-dir: "~/project/sample" cache-version: v5 pkg-manager: pnpm pnpm-run: build setup: - run: name: Remove other lock files command: | rm ~/project/sample/package-lock.json rm ~/project/sample/yarn.lock rm ~/project/sample/yarn-berry.lock rm ~/project/sample/bun.lock - node/run: filters: *filters name: node-run-bun-job app-dir: "~/project/sample" cache-version: v3 pkg-manager: bun bun-run: build cache-path: ~/.bun/install/cache setup: - node/install-bun: version: "1.2.22" - run: name: Remove other lock files command: | rm ~/project/sample/package-lock.json rm ~/project/sample/yarn.lock rm ~/project/sample/pnpm-lock.yaml rm ~/project/sample/yarn-berry.lock - integration-test-override-ci: matrix: alias: integration-test-override-ci parameters: resource_class: [arm.medium, medium] filters: *filters - integration-test-pnpm: matrix: alias: integration-test-pnpm parameters: resource_class: [arm.medium, medium] filters: *filters - integration-test-bun: matrix: alias: integration-test-bun parameters: resource_class: [arm.medium, medium] filters: *filters - integration-test-override-ci-windows: filters: *filters - integration-test-yarn: matrix: alias: integration-test-yarn parameters: resource_class: [arm.medium, medium] filters: *filters - integration-test-yarn-berry: matrix: alias: integration-test-yarn-berry parameters: resource_class: [arm.medium, medium] filters: *filters - integration-test-yarn-berry-nocimg: filters: *filters - orb-tools/pack: filters: *release-filters - orb-tools/publish: orb_name: circleci/node vcs_type: << pipeline.project.type >> pub_type: production requires: - orb-tools/pack - integration-test-override-ci-windows - integration-test-override-ci - integration-test-yarn - integration-test-yarn-berry - integration-test-yarn-berry-nocimg - integration-test-install-specified-version - integration-test-install-latest - integration-test-install-lts - integration-test-install-pnpm - integration-test-install-bun-specified - integration-test-pnpm - integration-test-bun - integration-test-reinstall-yarn - node-yarn-mocha-with-test-result-path-job - integration-test-override-yarn - node-yarn-mocha-test-job - node-yarn-jest-test-job - node-test-results-file-job - node-npm-jest-test-job - node-test-with-coverage - node-run-npm-job - node-pnpm-mocha-test-job - node-bun-jest-test-job - node-bun-mocha-test-job - node-bun-native-test-job - node-test-no-junit - node-pnpm-jest-test-job - node-run-yarn-job - node-run-pnpm-job - node-run-bun-job - node-run-upload-artifacts github_token: GHI_TOKEN context: orb-publisher filters: *release-filters Continuing pipeline... {"message":"OK"}Pipeline successfully continued. Continuation successful! Your orb will now be tested in the next workflow. View the full pipeline progress: https://app.circleci.com/pipelines/github/CircleCI-Public/node-orb/1211