From 7ae51127c65478920bfd5382e91257ce60b65319 Mon Sep 17 00:00:00 2001 From: "Mark S. Lewis" Date: Thu, 21 Mar 2024 18:22:16 +0000 Subject: [PATCH] Use Node 20 runtime in Docker image - Code remains compatible with Node 18. - Project continues to be built and tested with Node 18. - Node 20 is used as the runtime for the nodeenv Docker image to allow chaincode access to latest Node features and security fixes. Signed-off-by: Mark S. Lewis --- .github/settings.yml | 2 +- .github/workflows/pull_request.yaml | 2 +- .github/workflows/release.yaml | 5 - .github/workflows/test.yaml | 11 -- .gitignore | 2 + COMPATIBILITY.md | 41 +++--- TUTORIAL.md | 3 +- common/scripts/install-run-rush-pnpm.js | 2 +- common/scripts/install-run-rush.js | 9 +- common/scripts/install-run-rushx.js | 2 +- common/scripts/install-run.js | 119 ++++++++++++------ docker/fabric-nodeenv/Dockerfile | 5 +- .../tutorials/using-chaincodeinterface.md | 3 +- .../tutorials/using-contractinterface.md | 3 +- libraries/fabric-ledger/package.json | 2 +- libraries/fabric-shim/cli.js | 2 +- rush.json | 36 +----- test/chaincodes/clientidentity/package.json | 2 +- test/chaincodes/crosschaincode/package.json | 2 +- test/chaincodes/crosschaincode2/package.json | 2 +- test/chaincodes/crud/package.json | 2 +- test/chaincodes/events/package.json | 2 +- test/chaincodes/ledger/package.json | 2 +- test/chaincodes/privateData/package.json | 3 +- test/chaincodes/query/package.json | 2 +- test/chaincodes/scenario/package.json | 2 +- test/fv/package.json | 2 +- tools/scripts/updateversions.sh | 17 ++- 28 files changed, 150 insertions(+), 137 deletions(-) diff --git a/.github/settings.yml b/.github/settings.yml index 10b769521..74f013b6c 100644 --- a/.github/settings.yml +++ b/.github/settings.yml @@ -5,7 +5,7 @@ repository: homepage: https://wiki.hyperledger.org/display/fabric default_branch: main has_downloads: true - has_issues: false + has_issues: true has_projects: false has_wiki: false archived: false diff --git a/.github/workflows/pull_request.yaml b/.github/workflows/pull_request.yaml index cff1b3d4a..2cc20b287 100644 --- a/.github/workflows/pull_request.yaml +++ b/.github/workflows/pull_request.yaml @@ -22,4 +22,4 @@ jobs: name: Pull request success runs-on: ubuntu-latest steps: - - run: true + - run: 'true' diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 7b3a55000..54fa93ccf 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -10,7 +10,6 @@ on: workflow_dispatch: env: - CHAINCODE_CONTAINER_NODE_VER: 18 DOCKER_REGISTRY: ${{ github.repository_owner == 'hyperledger' && 'docker.io' || 'ghcr.io' }} jobs: @@ -47,7 +46,6 @@ jobs: steps: - name: Set up QEMU uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 with: @@ -55,7 +53,6 @@ jobs: config-inline: | [worker.oci] max-parallelism = 1 - - name: Checkout uses: actions/checkout@v4 @@ -86,5 +83,3 @@ jobs: tags: ${{ steps.meta.outputs.tags }} push: ${{ github.event_name != 'pull_request' }} labels: ${{ steps.meta.outputs.labels }} - build-args: | - NODE_VER=${{ env.CHAINCODE_CONTAINER_NODE_VER }} diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 00036aedd..6c6d4243e 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -15,9 +15,6 @@ jobs: BUILD_DATE: ${{ steps.builddata.outputs.BUILD_DATE }} steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: '18.x' - name: BuildData id: builddata run: | @@ -41,7 +38,6 @@ jobs: build: runs-on: ubuntu-20.04 - steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 @@ -61,19 +57,16 @@ jobs: with: name: TestResults path: ./**/test-results.xml - - name: Build Binaries run: | set -xev node common/scripts/install-run-rush.js publish --include-all --pack --release-folder tgz --publish docker image save hyperledger/fabric-nodeenv | gzip > fabric-nodeenv.tar.gz - - uses: actions/upload-artifact@v4 name: Binaries with: name: node-tgzs path: tgz/ - - uses: actions/upload-artifact@v4 name: Docker with: @@ -88,7 +81,6 @@ jobs: - uses: actions/setup-node@v4 with: node-version: '18.x' - - uses: actions/download-artifact@v4 with: name: nodeenv-docker-image @@ -97,7 +89,6 @@ jobs: with: name: node-tgzs path: build/ - - name: Setup the fv build env: PIPELINE_WORKSPACE: workspace @@ -111,7 +102,6 @@ jobs: node common/scripts/install-run-rush.js update # should the tests need 'building' this will need to go here node common/scripts/install-run-rush.js start-fabric node common/scripts/install-run-rush.js start-verdaccio # script will check for the ci variable and use built images - - name: Run the FV Tests run: | set -xev @@ -120,7 +110,6 @@ jobs: node common/scripts/install-run-rush.js test:fv --verbose node common/scripts/install-run-rush.js test:e2e --verbose - - uses: actions/upload-artifact@v4 if: ${{ !cancelled() }} name: TestLogs diff --git a/.gitignore b/.gitignore index cada7cd2b..da70bf862 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ yarn.lock **/typescript/*.js.map fabric*.tgz +install-fabric.sh libraries/fabric-ledger/lib @@ -28,6 +29,7 @@ common/temp/** **/.rush/temp/** **/*.build.error.log **/*.build.log +**/*.test_fv.log package-deps.json test-results.xml diff --git a/COMPATIBILITY.md b/COMPATIBILITY.md index dbc4a272f..1ccce16b6 100644 --- a/COMPATIBILITY.md +++ b/COMPATIBILITY.md @@ -6,22 +6,18 @@ Github is used for code base management, issues should reported in the repositor This table shows the summary of the compatibility of the Node modules at versions 1.4 and 2.x, together with the Node.js runtime they require and the Fabric Peer versions they can communicate with. -| | Peer Connectivity v1.4 | Supported NodeJS | Peer Connectivity v2.x | -| ------------------------------ | ---------------------- | ---------------- | ---------------------- | -| Node modules **v1.4.5** | Yes | 8 | Yes | -| Node modules **v2.2.x/v2.3.x** | Yes | 12 | Yes | -| Node modules **v2.4.x** | Yes | 16 | Yes | -| Node modules **v2.5.x** | Yes | 18 | Yes | +| Chaincode Docker image | Peer connectivity v1.4 | Peer connectivity v2.x | Minimum supported Node.js | Node.js runtime | +| --- | --- | --- | --- | --- | +| **v1.4.5** | Yes | Yes | 8 | 8 | +| **v2.2.x** | Yes | Yes | 12 | 12 | +| **v2.3.x** | Yes | Yes | 12 | 12 | +| **v2.4.x** | Yes | Yes | 16 | 16 | +| **v2.5.0** - **v2.5.4** | Yes | Yes | 18 | 18 | +| **v2.5.5+** | Yes | Yes | 18 | 20 | +Whilst these are defaults based on the corresponding `fabric-nodeenv` Docker image version, the Docker image used to host the chaincode and contracts can be altered. Set the environment variable `CORE_CHAINCODE_NODE_RUNTIME` on the peer to the name of the desired Docker image and version. -* Fabric peer v1.4 will create a Node.js v8 runtime -* Fabric peer v2.2/2.3 will create a Node.js 12 runtime -* Fabric peer v2.4 will create a Node.js 16 runtime -* Fabric peer v2.5 will create a Node.js 18 runtime - -Whilst these are defaults based on the corresponding `fabric-nodeenv` docker image version, the docker image used to host the chaincode and contracts can be altered. Set the environment variable `CORE_CHAINCODE_NODE_RUNTIME` on the peer to the name of the desired docker image and version. - -For example `CORE_CHAINCODE_NODE_RUNTIME=hyperledger/fabric-nodeenv:2.2` will allow the use of the latest Node 12 runtime to be used within a Peer v1.4. +For example `CORE_CHAINCODE_NODE_RUNTIME=hyperledger/fabric-nodeenv:2.2` will allow the use of a Node 12 runtime to be used within a Peer v1.4. The Node chaincode modules will connect to the peer whilst running; this is referred to as 'Fabric Peer Connectivity' in the table. For example, whilst the Fabric Peer v1.4 will create a Node.js 8 runtime, if a Node.js 12 runtime was configured, the node chaincode modules at v2.x still function when connecting to the Fabric Peer v1.4. @@ -39,7 +35,7 @@ The key elements are : - the version of the Node.js runtime used to run the code - When starting a chaincode container to run a Smart Contract, the version of the runtime that is used is determined by these factors: -Fabric v1.4.x, and Fabric v2.x will, by default, start up a docker container based on `fabric-nodeenv` to host the chaincode and contracts. The version of the docker image used is driven by the version of Fabric in use, but can be overridden by setting the peer's `CORE_CHAINCODE_NODE_RUNTIME` environment variable. +Fabric v1.4.x, and Fabric v2.x will, by default, start up a Docker container based on `fabric-nodeenv` to host the chaincode and contracts. The version of the Docker image used is driven by the version of Fabric in use, but can be overridden by setting the peer's `CORE_CHAINCODE_NODE_RUNTIME` environment variable. With Fabric v2.x, the chaincode container can be configured to be started by other means, and not the Peer. In this case, the environment used is not in the control of Fabric. @@ -50,19 +46,20 @@ Node modules that are produced are `fabric-contract-api`, `fabric-shim` & `fabri * Fabric v1.4 Node.js chaincode modules are supported running Nodejs 8.16.1 with the x86_64 architecture. * Fabric v2.2/v2.3 Node.js chaincode modules are supported running in Node.js 12.22.6, with the x86_64 architecture. * Fabric v2.4 Node.js chaincode modules are supported running in Node.js 16.x, with the x86_64 architecture. -* Fabric v2.5 Node.js chaincode modules are supported running in Node.js 18.x, with the x86_64 and arm64 architectures. +* Fabric v2.5.x Node.js chaincode modules are supported running in Node.js 18.x, with the x86_64 and arm64 architectures. -Architecture Support: all docker images, runtimes, tools are tested under x86_64 ONLY +Architecture Support: all Docker images, runtimes, tools are tested under x86_64 ONLY ### Default Peer Runtime selection -* Fabric 2.2/2.3 `fabric-nodeenv` docker image is based on node:12.22.6-alpine. -* Fabric 2.4 `fabric-nodeenv` docker image is based on node:16-alpine. -* Fabric 2.5 `fabric-nodeenv` docker image is based on node:18-alpine. +* Fabric 2.2/2.3 `fabric-nodeenv` Docker image is based on node:12.22.6-alpine. +* Fabric 2.4 `fabric-nodeenv` Docker image is based on node:16-alpine. +* Fabric 2.5.0 - 2.5.4 `fabric-nodeenv` Docker image is based on node:18-alpine. +* Fabric 2.5.5+ `fabric-nodeenv` Docker image is based on node:20-alpine. -*Note:* With the default docker image used by Fabric 2.x, the packaged code will be installed with npm. If a `package-lock.json` or a `npm-shrinkwrap.json` file is present, `npm ci --only=production` will be used. Otherwise `npm install --production` will be used.  +*Note:* With the default Docker image used by Fabric 2.x, the packaged code will be installed with npm. If a `package-lock.json` or a `npm-shrinkwrap.json` file is present, `npm ci --only=production` will be used. Otherwise `npm install --production` will be used.  -When using Fabric 1.4.x, the docker image that is used to run the Node.js chaincode is node v8.16.1. It is installed with npm install --production +When using Fabric 1.4.x, the Docker image that is used to run the Node.js chaincode is node v8.16.1. It is installed with npm install --production ### Supported Runtime communication with the Peer diff --git a/TUTORIAL.md b/TUTORIAL.md index 0a8ae2559..fcd1dccc2 100644 --- a/TUTORIAL.md +++ b/TUTORIAL.md @@ -15,8 +15,7 @@ The dependencies of `fabric-contract-api` and `fabric-shim` will be required. "name": "chaincode", "description": "My first exciting chaincode implemented in node.js", "engines": { - "node": "^12.16.1", - "npm": "^6.4.1" + "node": ">=18" }, "scripts": { "test": "mocha....." diff --git a/common/scripts/install-run-rush-pnpm.js b/common/scripts/install-run-rush-pnpm.js index 5c149955d..72a7bfdf0 100644 --- a/common/scripts/install-run-rush-pnpm.js +++ b/common/scripts/install-run-rush-pnpm.js @@ -19,7 +19,7 @@ var __webpack_exports__ = {}; \*****************************************************/ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. -// See the @microsoft/rush package's LICENSE file for license information. +// See LICENSE in the project root for license information. require('./install-run-rush'); //# sourceMappingURL=install-run-rush-pnpm.js.map module.exports = __webpack_exports__; diff --git a/common/scripts/install-run-rush.js b/common/scripts/install-run-rush.js index cada1eded..008e64411 100644 --- a/common/scripts/install-run-rush.js +++ b/common/scripts/install-run-rush.js @@ -113,7 +113,8 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! fs */ 657147); /* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_1__); // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. -// See the @microsoft/rush package's LICENSE file for license information. +// See LICENSE in the project root for license information. +/* eslint-disable no-console */ const { installAndRun, findRushJsonFolder, RUSH_JSON_FILENAME, runWithErrorAndStatusCode } = require('./install-run'); @@ -136,8 +137,8 @@ function _getRushVersion(logger) { return rushJsonMatches[1]; } catch (e) { - throw new Error(`Unable to determine the required version of Rush from rush.json (${rushJsonFolder}). ` + - "The 'rushVersion' field is either not assigned in rush.json or was specified " + + throw new Error(`Unable to determine the required version of Rush from ${RUSH_JSON_FILENAME} (${rushJsonFolder}). ` + + `The 'rushVersion' field is either not assigned in ${RUSH_JSON_FILENAME} or was specified ` + 'using an unexpected syntax.'); } } @@ -196,7 +197,7 @@ function _run() { } runWithErrorAndStatusCode(logger, () => { const version = _getRushVersion(logger); - logger.info(`The rush.json configuration requests Rush version ${version}`); + logger.info(`The ${RUSH_JSON_FILENAME} configuration requests Rush version ${version}`); const lockFilePath = process.env[INSTALL_RUN_RUSH_LOCKFILE_PATH_VARIABLE]; if (lockFilePath) { logger.info(`Found ${INSTALL_RUN_RUSH_LOCKFILE_PATH_VARIABLE}="${lockFilePath}", installing with lockfile.`); diff --git a/common/scripts/install-run-rushx.js b/common/scripts/install-run-rushx.js index b05df262b..0a0235f29 100644 --- a/common/scripts/install-run-rushx.js +++ b/common/scripts/install-run-rushx.js @@ -19,7 +19,7 @@ var __webpack_exports__ = {}; \*************************************************/ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. -// See the @microsoft/rush package's LICENSE file for license information. +// See LICENSE in the project root for license information. require('./install-run-rush'); //# sourceMappingURL=install-run-rushx.js.map module.exports = __webpack_exports__; diff --git a/common/scripts/install-run.js b/common/scripts/install-run.js index c04c587be..08b606a5a 100644 --- a/common/scripts/install-run.js +++ b/common/scripts/install-run.js @@ -21,6 +21,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "isVariableSetInNpmrcFile": () => (/* binding */ isVariableSetInNpmrcFile), /* harmony export */ "syncNpmrc": () => (/* binding */ syncNpmrc) /* harmony export */ }); /* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! fs */ 657147); @@ -33,23 +34,30 @@ __webpack_require__.r(__webpack_exports__); /** - * As a workaround, copyAndTrimNpmrcFile() copies the .npmrc file to the target folder, and also trims + * This function reads the content for given .npmrc file path, and also trims * unusable lines from the .npmrc file. * - * Why are we trimming the .npmrc lines? NPM allows environment variables to be specified in - * the .npmrc file to provide different authentication tokens for different registry. - * However, if the environment variable is undefined, it expands to an empty string, which - * produces a valid-looking mapping with an invalid URL that causes an error. Instead, - * we'd prefer to skip that line and continue looking in other places such as the user's - * home directory. - * * @returns * The text of the the .npmrc. */ -function _copyAndTrimNpmrcFile(logger, sourceNpmrcPath, targetNpmrcPath) { - logger.info(`Transforming ${sourceNpmrcPath}`); // Verbose - logger.info(` --> "${targetNpmrcPath}"`); - let npmrcFileLines = fs__WEBPACK_IMPORTED_MODULE_0__.readFileSync(sourceNpmrcPath).toString().split('\n'); +// create a global _combinedNpmrc for cache purpose +const _combinedNpmrcMap = new Map(); +function _trimNpmrcFile(options) { + const { sourceNpmrcPath, linesToPrepend, linesToAppend } = options; + const combinedNpmrcFromCache = _combinedNpmrcMap.get(sourceNpmrcPath); + if (combinedNpmrcFromCache !== undefined) { + return combinedNpmrcFromCache; + } + let npmrcFileLines = []; + if (linesToPrepend) { + npmrcFileLines.push(...linesToPrepend); + } + if (fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(sourceNpmrcPath)) { + npmrcFileLines.push(...fs__WEBPACK_IMPORTED_MODULE_0__.readFileSync(sourceNpmrcPath).toString().split('\n')); + } + if (linesToAppend) { + npmrcFileLines.push(...linesToAppend); + } npmrcFileLines = npmrcFileLines.map((line) => (line || '').trim()); const resultLines = []; // This finds environment variable tokens that look like "${VAR_NAME}" @@ -57,8 +65,13 @@ function _copyAndTrimNpmrcFile(logger, sourceNpmrcPath, targetNpmrcPath) { // Comment lines start with "#" or ";" const commentRegExp = /^\s*[#;]/; // Trim out lines that reference environment variables that aren't defined - for (const line of npmrcFileLines) { + for (let line of npmrcFileLines) { let lineShouldBeTrimmed = false; + //remove spaces before or after key and value + line = line + .split('=') + .map((lineToTrim) => lineToTrim.trim()) + .join('='); // Ignore comment lines if (!commentRegExp.test(line)) { const environmentVariables = line.match(expansionRegExp); @@ -85,27 +98,44 @@ function _copyAndTrimNpmrcFile(logger, sourceNpmrcPath, targetNpmrcPath) { } } const combinedNpmrc = resultLines.join('\n'); + //save the cache + _combinedNpmrcMap.set(sourceNpmrcPath, combinedNpmrc); + return combinedNpmrc; +} +function _copyAndTrimNpmrcFile(options) { + const { logger, sourceNpmrcPath, targetNpmrcPath, linesToPrepend, linesToAppend } = options; + logger.info(`Transforming ${sourceNpmrcPath}`); // Verbose + logger.info(` --> "${targetNpmrcPath}"`); + const combinedNpmrc = _trimNpmrcFile({ + sourceNpmrcPath, + linesToPrepend, + linesToAppend + }); fs__WEBPACK_IMPORTED_MODULE_0__.writeFileSync(targetNpmrcPath, combinedNpmrc); return combinedNpmrc; } -/** - * syncNpmrc() copies the .npmrc file to the target folder, and also trims unusable lines from the .npmrc file. - * If the source .npmrc file not exist, then syncNpmrc() will delete an .npmrc that is found in the target folder. - * - * IMPORTANT: THIS CODE SHOULD BE KEPT UP TO DATE WITH Utilities._syncNpmrc() - * - * @returns - * The text of the the synced .npmrc, if one exists. If one does not exist, then undefined is returned. - */ -function syncNpmrc(sourceNpmrcFolder, targetNpmrcFolder, useNpmrcPublish, logger = { - info: console.log, - error: console.error -}) { +function syncNpmrc(options) { + const { sourceNpmrcFolder, targetNpmrcFolder, useNpmrcPublish, logger = { + // eslint-disable-next-line no-console + info: console.log, + // eslint-disable-next-line no-console + error: console.error + }, createIfMissing = false, linesToAppend, linesToPrepend } = options; const sourceNpmrcPath = path__WEBPACK_IMPORTED_MODULE_1__.join(sourceNpmrcFolder, !useNpmrcPublish ? '.npmrc' : '.npmrc-publish'); const targetNpmrcPath = path__WEBPACK_IMPORTED_MODULE_1__.join(targetNpmrcFolder, '.npmrc'); try { - if (fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(sourceNpmrcPath)) { - return _copyAndTrimNpmrcFile(logger, sourceNpmrcPath, targetNpmrcPath); + if (fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(sourceNpmrcPath) || createIfMissing) { + // Ensure the target folder exists + if (!fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(targetNpmrcFolder)) { + fs__WEBPACK_IMPORTED_MODULE_0__.mkdirSync(targetNpmrcFolder, { recursive: true }); + } + return _copyAndTrimNpmrcFile({ + sourceNpmrcPath, + targetNpmrcPath, + logger, + linesToAppend, + linesToPrepend + }); } else if (fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(targetNpmrcPath)) { // If the source .npmrc doesn't exist and there is one in the target, delete the one in the target @@ -117,6 +147,16 @@ function syncNpmrc(sourceNpmrcFolder, targetNpmrcFolder, useNpmrcPublish, logger throw new Error(`Error syncing .npmrc file: ${e}`); } } +function isVariableSetInNpmrcFile(sourceNpmrcFolder, variableKey) { + const sourceNpmrcPath = `${sourceNpmrcFolder}/.npmrc`; + //if .npmrc file does not exist, return false directly + if (!fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(sourceNpmrcPath)) { + return false; + } + const trimmedNpmrcFile = _trimNpmrcFile({ sourceNpmrcPath }); + const variableKeyRegExp = new RegExp(`^${variableKey}=`, 'm'); + return trimmedNpmrcFile.match(variableKeyRegExp) !== null; +} //# sourceMappingURL=npmrcUtilities.js.map /***/ }), @@ -253,7 +293,8 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_3__); /* harmony import */ var _utilities_npmrcUtilities__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utilities/npmrcUtilities */ 679877); // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. -// See the @microsoft/rush package's LICENSE file for license information. +// See LICENSE in the project root for license information. +/* eslint-disable no-console */ @@ -393,7 +434,11 @@ function _resolvePackageVersion(logger, rushCommonFolder, { name, version }) { try { const rushTempFolder = _getRushTempFolder(rushCommonFolder); const sourceNpmrcFolder = path__WEBPACK_IMPORTED_MODULE_3__.join(rushCommonFolder, 'config', 'rush'); - (0,_utilities_npmrcUtilities__WEBPACK_IMPORTED_MODULE_4__.syncNpmrc)(sourceNpmrcFolder, rushTempFolder, undefined, logger); + (0,_utilities_npmrcUtilities__WEBPACK_IMPORTED_MODULE_4__.syncNpmrc)({ + sourceNpmrcFolder, + targetNpmrcFolder: rushTempFolder, + logger + }); const npmPath = getNpmPath(); // This returns something that looks like: // ``` @@ -426,9 +471,9 @@ function _resolvePackageVersion(logger, rushCommonFolder, { name, version }) { : [parsedVersionOutput]; let latestVersion = versions[0]; for (let i = 1; i < versions.length; i++) { - const version = versions[i]; - if (_compareVersionStrings(version, latestVersion) > 0) { - latestVersion = version; + const latestVersionCandidate = versions[i]; + if (_compareVersionStrings(latestVersionCandidate, latestVersion) > 0) { + latestVersion = latestVersionCandidate; } } if (!latestVersion) { @@ -460,7 +505,7 @@ function findRushJsonFolder() { } } while (basePath !== (tempPath = path__WEBPACK_IMPORTED_MODULE_3__.dirname(basePath))); // Exit the loop when we hit the disk root if (!_rushJsonFolder) { - throw new Error('Unable to find rush.json.'); + throw new Error(`Unable to find ${RUSH_JSON_FILENAME}.`); } } return _rushJsonFolder; @@ -591,7 +636,11 @@ function installAndRun(logger, packageName, packageVersion, packageBinName, pack // The package isn't already installed _cleanInstallFolder(rushTempFolder, packageInstallFolder, lockFilePath); const sourceNpmrcFolder = path__WEBPACK_IMPORTED_MODULE_3__.join(rushCommonFolder, 'config', 'rush'); - (0,_utilities_npmrcUtilities__WEBPACK_IMPORTED_MODULE_4__.syncNpmrc)(sourceNpmrcFolder, packageInstallFolder, undefined, logger); + (0,_utilities_npmrcUtilities__WEBPACK_IMPORTED_MODULE_4__.syncNpmrc)({ + sourceNpmrcFolder, + targetNpmrcFolder: packageInstallFolder, + logger + }); _createPackageJson(packageInstallFolder, packageName, packageVersion); const command = lockFilePath ? 'ci' : 'install'; _installPackage(logger, packageInstallFolder, packageName, packageVersion, command); diff --git a/docker/fabric-nodeenv/Dockerfile b/docker/fabric-nodeenv/Dockerfile index c8c7e52ae..13869cf27 100644 --- a/docker/fabric-nodeenv/Dockerfile +++ b/docker/fabric-nodeenv/Dockerfile @@ -2,8 +2,7 @@ # # SPDX-License-Identifier: Apache-2.0 # -ARG NODE_VER=18 -FROM node:${NODE_VER}-alpine +FROM node:20-alpine RUN apk add --no-cache \ make \ python3 \ @@ -11,4 +10,4 @@ RUN apk add --no-cache \ RUN mkdir -p /chaincode/input \ && mkdir -p /chaincode/output \ && mkdir -p /usr/local/src; -ADD build.sh start.sh /chaincode/ \ No newline at end of file +ADD build.sh start.sh /chaincode/ diff --git a/docs/_jsdoc/tutorials/using-chaincodeinterface.md b/docs/_jsdoc/tutorials/using-chaincodeinterface.md index 39241dce5..b0cac069d 100644 --- a/docs/_jsdoc/tutorials/using-chaincodeinterface.md +++ b/docs/_jsdoc/tutorials/using-chaincodeinterface.md @@ -60,8 +60,7 @@ Finally, update the "start" script in package.json to "node mychaincode.js": "version": "1.0.0", "description": "My first exciting chaincode implemented in node.js", "engines": { - "node": "^12.16.1", - "npm": "^6.4.1" + "node": "^>=18" }, "scripts": { "start" : "node mychaincode.js" }, "engine-strict": true, diff --git a/docs/_jsdoc/tutorials/using-contractinterface.md b/docs/_jsdoc/tutorials/using-contractinterface.md index f88e779f7..dd1979b1d 100644 --- a/docs/_jsdoc/tutorials/using-contractinterface.md +++ b/docs/_jsdoc/tutorials/using-contractinterface.md @@ -15,8 +15,7 @@ The dependencies of `fabric-contract-api` and `fabric-shim` will be required. "name": "chaincode", "description": "My first exciting chaincode implemented in node.js", "engines": { - "node": "^12.16.1", - "npm": "^6.4.1" + "node": ">=18" }, "scripts": { "test":"mocha..... diff --git a/libraries/fabric-ledger/package.json b/libraries/fabric-ledger/package.json index dbba7a97b..51d3b7fad 100644 --- a/libraries/fabric-ledger/package.json +++ b/libraries/fabric-ledger/package.json @@ -23,7 +23,7 @@ "Fabric Ledger" ], "engines": { - "node": "^18.0.0" + "node": ">=18" }, "license": "Apache-2.0", "nyc": { diff --git a/libraries/fabric-shim/cli.js b/libraries/fabric-shim/cli.js index 3e3624b3f..4f439471e 100755 --- a/libraries/fabric-shim/cli.js +++ b/libraries/fabric-shim/cli.js @@ -30,5 +30,5 @@ const main = async () => { main().catch( (e)=> { console.error("Major failure to start fabic-chaincode-node"); console.error(e); - process.exit(1); + process.exitCode = 1; }); diff --git a/rush.json b/rush.json index f286d8dcb..38781e5e5 100644 --- a/rush.json +++ b/rush.json @@ -15,7 +15,7 @@ * path segment in the "$schema" field for all your Rush config files. This will ensure * correct error-underlining and tab-completion for editors such as VS Code. */ - "rushVersion": "5.104.0", + "rushVersion": "5.118.1", /** * The next field selects which package manager should be installed and determines its version. * Rush installs its own local copy of the package manager to ensure that your build process @@ -24,7 +24,7 @@ * Specify one of: "pnpmVersion", "npmVersion", or "yarnVersion". See the Rush documentation * for details about these alternatives. */ - "pnpmVersion": "8.7.1", + "pnpmVersion": "8.15.5", /** * Options that are only used when the PNPM package manager is selected */ @@ -62,7 +62,7 @@ * Specify a SemVer range to ensure developers use a Node.js version that is appropriate * for your repo. */ - "nodeSupportedVersionRange": ">=18.12.0 <19.0.0", + "nodeSupportedVersionRange": ">=18", /** * Odd-numbered major versions of Node.js are experimental. Even-numbered releases * spend six months in a stabilization period before the first Long Term Support (LTS) version. @@ -223,36 +223,6 @@ */ "postRushBuild": [] }, - /** - * Installation variants allow you to maintain a parallel set of configuration files that can be - * used to build the entire monorepo with an alternate set of dependencies. For example, suppose - * you upgrade all your projects to use a new release of an important framework, but during a transition period - * you intend to maintain compability with the old release. In this situation, you probably want your - * CI validation to build the entire repo twice: once with the old release, and once with the new release. - * - * Rush "installation variants" correspond to sets of config files located under this folder: - * - * common/config/rush/variants/ - * - * The variant folder can contain an alternate common-versions.json file. Its "preferredVersions" field can be used - * to select older versions of dependencies (within a loose SemVer range specified in your package.json files). - * To install a variant, run "rush install --variant ". - * - * For more details and instructions, see this article: https://rushjs.io/pages/advanced/installation_variants/ - */ - "variants": [ - // { - // /** - // * The folder name for this variant. - // */ - // "variantName": "old-sdk", - // - // /** - // * An informative description - // */ - // "description": "Build this repo using the previous release of the SDK" - // } - ], /** * Rush can collect anonymous telemetry about everyday developer activity such as * success/failure of installs, builds, and other operations. You can use this to identify diff --git a/test/chaincodes/clientidentity/package.json b/test/chaincodes/clientidentity/package.json index daf9186e6..0a15dd47c 100644 --- a/test/chaincodes/clientidentity/package.json +++ b/test/chaincodes/clientidentity/package.json @@ -2,7 +2,7 @@ "name": "chaincode", "description": "Chaincode testing ClientIdentity functionality", "engines": { - "node": "^18.0.0" + "node": ">=18" }, "scripts": { "start": "fabric-chaincode-node start" diff --git a/test/chaincodes/crosschaincode/package.json b/test/chaincodes/crosschaincode/package.json index 0c4add61b..6ee33dd52 100644 --- a/test/chaincodes/crosschaincode/package.json +++ b/test/chaincodes/crosschaincode/package.json @@ -2,7 +2,7 @@ "name": "chaincode", "description": "Chaincode testing cross chaincode functionality", "engines": { - "node": "^18.0.0" + "node": ">=18" }, "scripts": { "start": "set -x && CORE_CHAINCODE_LOGGING_LEVEL=debug fabric-chaincode-node start" diff --git a/test/chaincodes/crosschaincode2/package.json b/test/chaincodes/crosschaincode2/package.json index b3567b50e..7120efbed 100644 --- a/test/chaincodes/crosschaincode2/package.json +++ b/test/chaincodes/crosschaincode2/package.json @@ -2,7 +2,7 @@ "name": "chaincode", "description": "Chaincode testing cross chaincode functionality", "engines": { - "node": "^18.0.0" + "node": ">=18" }, "scripts": { "start": "fabric-chaincode-node start" diff --git a/test/chaincodes/crud/package.json b/test/chaincodes/crud/package.json index a6d64df65..d9e84e658 100644 --- a/test/chaincodes/crud/package.json +++ b/test/chaincodes/crud/package.json @@ -2,7 +2,7 @@ "name": "chaincode", "description": "Chaincode testing crud functionality", "engines": { - "node": "^18.0.0" + "node": ">=18" }, "scripts": { "start": "set -x && CORE_CHAINCODE_LOGGING_LEVEL=debug fabric-chaincode-node start" diff --git a/test/chaincodes/events/package.json b/test/chaincodes/events/package.json index d69f61f2d..ca1c8de5a 100644 --- a/test/chaincodes/events/package.json +++ b/test/chaincodes/events/package.json @@ -2,7 +2,7 @@ "name": "chaincode", "description": "Chaincode testing events functionality", "engines": { - "node": "^18.0.0" + "node": ">=18" }, "scripts": { "start": "set -x && CORE_CHAINCODE_LOGGING_LEVEL=debug fabric-chaincode-node start" diff --git a/test/chaincodes/ledger/package.json b/test/chaincodes/ledger/package.json index 153a49ac7..3bc7b28c5 100644 --- a/test/chaincodes/ledger/package.json +++ b/test/chaincodes/ledger/package.json @@ -2,7 +2,7 @@ "name": "chaincode", "description": "Chaincode testing ledger functionality", "engines": { - "node": "^18.0.0" + "node": ">=18" }, "scripts": { "start": "fabric-chaincode-node start" diff --git a/test/chaincodes/privateData/package.json b/test/chaincodes/privateData/package.json index 67e3a194b..d8859e141 100644 --- a/test/chaincodes/privateData/package.json +++ b/test/chaincodes/privateData/package.json @@ -2,8 +2,7 @@ "name": "chaincode", "description": "Chaincode testing private data functionality", "engines": { - "node": "^18.0.0", - "npm": ">=5.3.0" + "node": ">=18" }, "scripts": { "start": "fabric-chaincode-node start" diff --git a/test/chaincodes/query/package.json b/test/chaincodes/query/package.json index 0026b142c..32efac9d6 100644 --- a/test/chaincodes/query/package.json +++ b/test/chaincodes/query/package.json @@ -2,7 +2,7 @@ "name": "chaincode", "description": "Chaincode testing query functionality", "engines": { - "node": "^18.0.0" + "node": ">=18" }, "scripts": { "start": "fabric-chaincode-node start" diff --git a/test/chaincodes/scenario/package.json b/test/chaincodes/scenario/package.json index 01df0fd67..bf9cf3507 100644 --- a/test/chaincodes/scenario/package.json +++ b/test/chaincodes/scenario/package.json @@ -2,7 +2,7 @@ "name": "chaincode", "description": "My first exciting chaincode implemented in node.js", "engines": { - "node": "^18.0.0" + "node": ">=18" }, "scripts": { "start": "fabric-chaincode-node start" diff --git a/test/fv/package.json b/test/fv/package.json index aa79bb6df..e863b8803 100644 --- a/test/fv/package.json +++ b/test/fv/package.json @@ -6,7 +6,7 @@ "testFabricThirdParty": "0.4.15", "docsLatestVersion": "release-1.4", "engines": { - "node": "^18.0.0" + "node": ">=18" }, "engineStrict": true, "license": "Apache-2.0", diff --git a/tools/scripts/updateversions.sh b/tools/scripts/updateversions.sh index 5c223e4f6..1603b924e 100755 --- a/tools/scripts/updateversions.sh +++ b/tools/scripts/updateversions.sh @@ -10,9 +10,24 @@ fi NEW_VERSION="$1" echo "Setting new version to '${NEW_VERSION}'" +DEPENDENCIES=( fabric-contract-api fabric-shim-api fabric-ledger toolchain ) + +updatePackageVersion() { + npm --allow-same-version --no-git-tag-version version "$1" + for dependency in "${DEPENDENCIES[@]}"; do + updateDependencyVersion "${dependency}" "$1" + done +} + +updateDependencyVersion() { + local packageJson + packageJson=$(node -e "const pkg = require('./package.json'); if (pkg.dependencies['$1']) pkg.dependencies['$1'] = '$2'; console.log(JSON.stringify(pkg, undefined, 2))") + echo "${packageJson}" > package.json +} + while read -r PACKAGE; do echo "Updating '${PACKAGE}'" - ( cd "$(dirname "${PACKAGE}")" && npm --allow-same-version --no-git-tag-version version "${NEW_VERSION}" ) + ( cd "$(dirname "${PACKAGE}")" && updatePackageVersion "${NEW_VERSION}" ) done <<< "$(find . -type d \( -name node_modules -o -name common \) -prune -o -type f -name package.json -print)" MAJOR_MINOR=$(cut -d. -f-2 <<< "${NEW_VERSION}")