diff --git a/.github/workflows/solidity.yml b/.github/workflows/solidity.yml index 7275f1f6261..79afb8c1d59 100644 --- a/.github/workflows/solidity.yml +++ b/.github/workflows/solidity.yml @@ -42,27 +42,57 @@ jobs: name: Tag Check runs-on: ubuntu-latest outputs: - is-release: ${{ steps.release-tag-check.outputs.is-release }} - is-pre-release: ${{ steps.release-tag-check.outputs.is-pre-release }} - release-version: ${{ steps.release-tag-check.outputs.release-version }} - pre-release-version: ${{ steps.release-tag-check.outputs.pre-release-version }} + is-release-core: ${{ steps.release-tag-check-core.outputs.is-release }} + is-pre-release-core: ${{ steps.release-tag-check-core.outputs.is-pre-release }} + release-version-core: ${{ steps.release-tag-check-core.outputs.release-version }} + pre-release-version-core: ${{ steps.release-tag-check-core.outputs.pre-release-version }} + is-release-ccip: ${{ steps.release-tag-check-ccip.outputs.is-release }} + is-pre-release-ccip: ${{ steps.release-tag-check-ccip.outputs.is-pre-release }} + release-version-ccip: ${{ steps.release-tag-check-ccip.outputs.release-version }} + pre-release-version-ccip: ${{ steps.release-tag-check-ccip.outputs.pre-release-version }} steps: - uses: actions/checkout@v4.2.1 with: persist-credentials: false - - name: Check release tag - id: release-tag-check - uses: smartcontractkit/chainlink-github-actions/release/release-tag-check@5dd916d08c03cb5f9a97304f4f174820421bb946 # v2.3.11 + - name: Check release tag (core) + id: release-tag-check-core + uses: smartcontractkit/.github/actions/release-tag-check@c5c4a8186da4218cff6cac8184e47dd3dec69ba3 # release-tag-check@0.1.0 env: # Match semver git tags with a "contracts-" prefix. RELEASE_REGEX: '^contracts-v[0-9]+\.[0-9]+\.[0-9]+$' PRE_RELEASE_REGEX: '^contracts-v[0-9]+\.[0-9]+\.[0-9]+-(.+)$' # Get the version by stripping the "contracts-v" prefix. - VERSION_PREFIX: 'contracts-v' + VERSION_PREFIX: "contracts-v" + - name: Check release tag (ccip) + id: release-tag-check-ccip + uses: smartcontractkit/.github/actions/release-tag-check@c5c4a8186da4218cff6cac8184e47dd3dec69ba3 # release-tag-check@0.1.0 + env: + # Match semver git tags with a "contracts-ccip/" prefix. + RELEASE_REGEX: '^contracts-ccip/v[0-9]+\.[0-9]+\.[0-9]+$' + PRE_RELEASE_REGEX: '^contracts-ccip/v[0-9]+\.[0-9]+\.[0-9]+-(.+)$' + # Get the version by stripping the "contracts-v" prefix. + VERSION_PREFIX: "contracts-ccip/v" + # CCIP release detected but: + # - contracts/package.json needs to be copied from: contracts/release/ccip/package.json + # - contracts/README.md needs to be copied from: contracts/release/ccip/README.md + # This should all happen before a CCIP contracts tag is published. + - name: Fail if CCIP files not updated + if: ${{ steps.release-tag-check-ccip.outputs.is-release == 'true' }} + shell: bash + run: | + error_msg="CCIP release detected but contracts/package.json or contracts/README.md is not up to date. Copy contracts/release/ccip/package.json and contracts/release/ccip/README.md to contracts/ and re-trigger workflow." + shasum_package_1=$(sha256sum contracts/package.json | awk '{print $1}') + shasum_package_2=$(sha256sum contracts/release/ccip/package.json | awk '{print $1}') + shasum_readme_1=$(sha256sum contracts/README.md | awk '{print $1}') + shasum_readme_2=$(sha256sum contracts/release/ccip/README.md | awk '{print $1}') + if [[ $shasum_package_1 != $shasum_package_2 || $shasum_readme_1 != $shasum_readme_2 ]]; then + echo "::error::${error_msg}" + exit 1 + fi prepublish-test: needs: [changes, tag-check] - if: needs.changes.outputs.changes == 'true' || needs.tag-check.outputs.is-pre-release == 'true' + if: needs.changes.outputs.changes == 'true' || (needs.tag-check.outputs.is-pre-release-core == 'true' || needs.tag-check.outputs.is-pre-release-ccip == 'true') name: Prepublish Test runs-on: ubuntu-latest steps: @@ -78,7 +108,7 @@ jobs: native-compile: needs: [changes, tag-check] - if: needs.changes.outputs.changes == 'true' || needs.tag-check.outputs.is-release == 'true' || needs.tag-check.outputs.is-pre-release == 'true' + if: needs.changes.outputs.changes == 'true' || needs.tag-check.outputs.is-release-core == 'true' || needs.tag-check.outputs.is-pre-release-core == 'true' name: Native Compilation runs-on: ubuntu-latest steps: @@ -176,7 +206,7 @@ jobs: name: Publish Beta NPM environment: publish-contracts needs: [tag-check, changes, lint, prettier, native-compile, prepublish-test] - if: needs.tag-check.outputs.is-pre-release == 'true' + if: needs.tag-check.outputs.is-pre-release-core == 'true' || needs.tag-check.outputs.is-pre-release-ccip == 'true' runs-on: ubuntu-latest steps: - name: Checkout the repo @@ -189,9 +219,24 @@ jobs: - name: Version package.json working-directory: contracts + shell: bash + env: + IS_PRE_RELEASE_CORE: ${{ needs.tag-check.outputs.is-pre-release-core }} + IS_PRE_RELEASE_CCIP: ${{ needs.tag-check.outputs.is-pre-release-ccip }} + PRE_RELEASE_VERSION_CORE: ${{ needs.tag-check.outputs.pre-release-version-core }} + PRE_RELEASE_VERSION_CCIP: ${{ needs.tag-check.outputs.pre-release-version-ccip }} run: | - echo "Bumping version to ${{ needs.tag-check.outputs.pre-release-version }}" - pnpm version ${{ needs.tag-check.outputs.pre-release-version }} --no-git-tag-version --no-commit-hooks --no-git-checks + version="" + if [[ $IS_PRE_RELEASE_CORE == 'true' ]]; then + version="${PRE_RELEASE_VERSION_CORE}" + elif [[ $IS_PRE_RELEASE_CCIP == 'true' ]]; then + version="${PRE_RELEASE_VERSION_CCIP}" + else + echo "::error::No pre-release version found." + exit 1 + fi + echo "Bumping version to ${version}" + pnpm version "${version}" --no-git-tag-version --no-commit-hooks --no-git-checks - name: Publish to NPM (beta) uses: smartcontractkit/.github/actions/ci-publish-npm@4b0ab756abcb1760cb82e1e87b94ff431905bffc # ci-publish-npm@0.4.0 @@ -205,7 +250,7 @@ jobs: name: Publish Prod NPM environment: publish-contracts needs: [tag-check, changes, lint, prettier, native-compile, prepublish-test] - if: needs.tag-check.outputs.is-release == 'true' + if: needs.tag-check.outputs.is-release-core == 'true' || needs.tag-check.outputs.is-release-ccip == 'true' runs-on: ubuntu-latest permissions: contents: write @@ -220,10 +265,25 @@ jobs: - name: Validate version working-directory: contracts + shell: bash + env: + IS_RELEASE_CORE: ${{ needs.tag-check.outputs.is-release-core }} + IS_RELEASE_CCIP: ${{ needs.tag-check.outputs.is-release-ccip }} + RELEASE_VERSION_CORE: ${{ needs.tag-check.outputs.release-version-core }} + RELEASE_VERSION_CCIP: ${{ needs.tag-check.outputs.release-version-ccip }} run: | - PACKAGE_JSON_VERSION="$(cat package.json | jq -r '.version')" - if [ "$PACKAGE_JSON_VERSION" != "${{ needs.tag-check.outputs.release-version }}" ]; then - echo "::error version mismatch: package.json version ($PACKAGE_JSON_VERSION) does not match version computed from tag ${{ needs.tag-check.outputs.release-version }}" + version="" + if [[ $IS_RELEASE_CORE == 'true' ]]; then + version="${RELEASE_VERSION_CORE}" + elif [[ $IS_RELEASE_CCIP == 'true' ]]; then + version="${RELEASE_VERSION_CCIP}" + else + echo "::error::No release version found." + exit 1 + fi + package_json_version="$(jq -r '.version' package.json)" + if [[ "$PACKAGE_JSON_VERSION" != "${version}" ]]; then + echo "::error version mismatch: package.json version ($package_json_version) does not match version computed from tag ${version}" exit 1 fi diff --git a/contracts/package.json b/contracts/package.json index 1e4da89843a..2401451cbec 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -19,11 +19,15 @@ "publish-beta": "pnpm publish --tag beta", "publish-prod": "pnpm publish --tag latest", "solhint": "solhint --max-warnings 0 \"./src/v0.8/**/*.sol\"", - "solhint-test": "solhint --config \".solhint-test.json\" --ignore-path \".solhintignore-test\" --max-warnings 0 \"./src/v0.8/**/*.sol\"" + "solhint-test": "solhint --config \".solhint-test.json\" --ignore-path \".solhintignore-test\" --max-warnings 0 \"./src/v0.8/**/*.sol\"", + "changeset:ccip": "pushd . && cd ./release/ccip && changeset && popd", + "copy:ccip-files": "cp ./release/ccip/package.json ./ && cp ./release/ccip/README.md ./" }, "files": [ "src/v0.8", - "abi/v0.8" + "abi/v0.8", + "!src/*/ccip/**", + "!src/*/liquiditymanager/**" ], "pnpm": { "_comment": "See https://github.com/ethers-io/ethers.js/discussions/2849#discussioncomment-2696454", diff --git a/contracts/release/ccip/.changeset/README.md b/contracts/release/ccip/.changeset/README.md new file mode 100644 index 00000000000..e5b6d8d6a67 --- /dev/null +++ b/contracts/release/ccip/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/contracts/release/ccip/.changeset/config.json b/contracts/release/ccip/.changeset/config.json new file mode 100644 index 00000000000..c5f760594dc --- /dev/null +++ b/contracts/release/ccip/.changeset/config.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@2.3.1/schema.json", + "changelog": [ + "../../.changeset/changelog-generator.js", + { + "repo": "smartcontractkit/chainlink" + } + ], + "commit": false, + "fixed": [], + "linked": [], + "access": "public", + "baseBranch": "develop", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/contracts/release/ccip/CHANGELOG.md b/contracts/release/ccip/CHANGELOG.md new file mode 100644 index 00000000000..fc9030323b4 --- /dev/null +++ b/contracts/release/ccip/CHANGELOG.md @@ -0,0 +1,14 @@ +# @chainlink/contracts-ccip + +## 1.5.0 + +### Minor Changes + +- [#14266](https://github.com/smartcontractkit/chainlink/pull/14266) [`c323e0d`](https://github.com/smartcontractkit/chainlink/commit/c323e0d600c659a4ea584dbae0a0db187afd51eb) Thanks [@asoliman92](https://github.com/asoliman92)! - #updated move latest ccip contracts code from ccip repo to chainlink repo +- [#13941](https://github.com/smartcontractkit/chainlink/pull/13941) [`9e74eee`](https://github.com/smartcontractkit/chainlink/commit/9e74eee9d415b386db33bdf2dd44facc82cd3551) Thanks [@RensR](https://github.com/RensR)! - add ccip contracts to the repo + +### Patch Changes + +- [#14345](https://github.com/smartcontractkit/chainlink/pull/14345) [`c83c687`](https://github.com/smartcontractkit/chainlink/commit/c83c68735bdee6bbd8510733b7415797cd08ecbd) Thanks [@makramkd](https://github.com/makramkd)! - #internal merge ccip contracts +- [#14516](https://github.com/smartcontractkit/chainlink/pull/14516) [`0e32c07`](https://github.com/smartcontractkit/chainlink/commit/0e32c07d22973343e722a228ff1c3b1e8f9bc04e) Thanks [@mateusz-sekara](https://github.com/mateusz-sekara)! - Adding USDCReaderTester contract for CCIP integration tests #internal +- [#14739](https://github.com/smartcontractkit/chainlink/pull/14739) [`4842271`](https://github.com/smartcontractkit/chainlink/commit/4842271b0f7054f5f1364c59d3d9da534c5d4f25) Thanks [@RensR](https://github.com/RensR)! - #internal remove CCIP 1.5 diff --git a/contracts/release/ccip/NOTES.md b/contracts/release/ccip/NOTES.md new file mode 100644 index 00000000000..284f252f530 --- /dev/null +++ b/contracts/release/ccip/NOTES.md @@ -0,0 +1,29 @@ +# Chainlink CCIP Smart Contracts + +This directory contains the changelogs, version (via `package.json`), and the changesets for the CCIP contracts. + +## Overview + +The actual CCIP contracts code currently lives in the `contracts/src/*/ccip` directory in order to share code with other Chainlink contracts. Even though this CCIP code directory is under the `@chainlink/contracts`'s `package.json` file, it's not part of the `@chainlink/contracts` NPM package and should be versioned, released, and published separately which is why this directory exists. + +## Create a Changeset + +To be ran from the (`./contracts`) directory. + +1. Create a changeset for your changes: + + ```shell + pnpm changeset:ccip + ``` + +2. Follow the prompts to describe your changes +3. Commit the generated changeset file + +## CCIP Contracts Release + +To be ran from the (`./contracts`) directory. Copy files over from `./contracts/release/ccip`/ to `./contracts/`. + +```shell +# To undo the copy, run `git checkout -- package.json README.md` +pnpm copy:ccip-files +``` diff --git a/contracts/release/ccip/README.md b/contracts/release/ccip/README.md new file mode 100644 index 00000000000..ee1fb134f85 --- /dev/null +++ b/contracts/release/ccip/README.md @@ -0,0 +1,51 @@ +# Chainlink CCIP Smart Contracts + +## Installation + +```sh +# via pnpm +$ pnpm add @chainlink/contracts-ccip +# via npm +$ npm install @chainlink/contracts-ccip --save +``` + +### Directory Structure + +```sh +@chainlink/contracts-ccip +├── src # Solidity contracts +│ └── v0.8 +└── abi # ABI json output + └── v0.8 +``` + +### Usage + +The solidity smart contracts themselves can be imported via the `src` directory of `@chainlink/contracts-ccip`: + +```solidity +import '@chainlink/contracts-ccip/src/v0.8/ccip/applications/CCIPReceiver.sol'; +``` + +### Changesets + +We use [changesets](https://github.com/changesets/changesets) to manage versioning the contracts. + +Every PR that modifies any configuration or code, should most likely accompanied by a changeset file. + +To install `changesets`: + +1. Install `pnpm` if it is not already installed - [docs](https://pnpm.io/installation). +2. Run `pnpm install`. + +Either after or before you create a commit, run the `pnpm changeset:ccip` command in the `contracts` directory to create an accompanying changeset entry which will reflect on the CHANGELOG for the next release. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## License + +The CCIP repo is licensed under the [BUSL-1.1](./src/v0.8/ccip/LICENSE.md) license, however, there are a few exceptions + +- `src/v0.8/ccip/applications/*` is licensed under the [MIT](./src/v0.8/ccip/LICENSE-MIT.md) license +- `src/v0.8/ccip/interfaces/*` is licensed under the [MIT](./src/v0.8/ccip/LICENSE-MIT.md) license +- `src/v0.8/ccip/libraries/{Client.sol, Internal.sol}` is licensed under the [MIT](./src/v0.8/ccip/LICENSE-MIT.md) license diff --git a/contracts/release/ccip/package.json b/contracts/release/ccip/package.json new file mode 100644 index 00000000000..dee0d987930 --- /dev/null +++ b/contracts/release/ccip/package.json @@ -0,0 +1,55 @@ +{ + "name": "@chainlink/contracts-ccip", + "version": "1.6.0", + "description": "Chainlink smart contracts for CCIP", + "author": "Chainlink devs", + "license": "BUSL-1.1", + "private": false, + "scripts": { + "publish-beta": "pnpm publish --tag beta", + "publish-prod": "npm dist-tag add @chainlink/contracts-ccip@1.6.0 latest", + "compile": "./scripts/native_solc_compile_all_ccip", + "prepublishOnly": "pnpm compile", + "verify:ccip-files": "diff ./release/ccip/package.json ./package.json && diff ./release/ccip/README.md ./README.md" + }, + "files": [ + "foundry.toml", + "src/v0.8/ccip/**/*.sol", + "src/v0.8/shared/access/*.sol", + "src/v0.8/shared/call/CallWithExactGas.sol", + "src/v0.8/shared/enumerable/EnumerableMapBytes32.sol", + "src/v0.8/shared/enumerable/EnumerableMapAddresses.sol", + "src/v0.8/shared/enumerable/EnumerableSetWithBytes16.sol", + "src/v0.8/shared/interfaces/IOwnable.sol", + "src/v0.8/shared/interfaces/ITypeAndVersion.sol", + "src/v0.8/shared/interfaces/IERC677Receiver.sol", + "src/v0.8/shared/interfaces/AggregatorV3Interface.sol", + "src/v0.8/shared/interfaces/AccessControllerInterface.sol", + "src/v0.8/shared/token/**/*.sol", + "src/v0.8/shared/util/SortedSetValidationUtil.sol", + "src/v0.8/liquiditymanager/interfaces/ILiquidityContainer.sol", + "src/v0.8/keystone/interfaces/**/*", + "src/v0.8/keystone/KeystoneFeedsPermissionHandler.sol", + "src/v0.8/keystone/lib/KeystoneFeedDefaultMetadataLib.sol", + "src/v0.8/vendor/openzeppelin-solidity/v4.8.3", + "src/v0.8/vendor/openzeppelin-solidity/v5.0.2", + "src/v0.8/vendor/Context.sol", + "src/v0.8/vendor/Pausable.sol", + "abi/v0.8/", + "src/v0.8/ccip/LICENSE.md", + "src/v0.8/ccip/v1.5-CCIP-License-grants.md", + "!src/v0.8/ccip/test/**/*", + "src/v0.8/ccip/test/mocks/**/*", + "!src/v0.8/ccip/test/mocks/test/*", + "scripts/native_solc_compile_all_ccip" + ], + "engines": { + "node": ">=18", + "pnpm": ">=9" + }, + "dependencies": { + "@changesets/cli": "~2.27.8", + "@changesets/get-github-info": "^0.6.0", + "semver": "^7.6.3" + } +} diff --git a/contracts/scripts/native_solc_compile_all_ccip b/contracts/scripts/native_solc_compile_all_ccip index 1dc6ff032f9..91ce5ef8729 100755 --- a/contracts/scripts/native_solc_compile_all_ccip +++ b/contracts/scripts/native_solc_compile_all_ccip @@ -12,9 +12,11 @@ OPTIMIZE_RUNS_OFFRAMP=800 OPTIMIZE_RUNS_FEE_QUOTER=10000 PROJECT="ccip" FOUNDRY_PROJECT_SUFFIX="-compile" +export FOUNDRY_PROFILE="$PROJECT"$FOUNDRY_PROJECT_SUFFIX CONTRACTS_DIR="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; cd ../ && pwd -P )" -export FOUNDRY_PROFILE="$PROJECT"$FOUNDRY_PROJECT_SUFFIX +ABI_DIR="$CONTRACTS_DIR"/abi/v0.8/ +mkdir -p "$ABI_DIR" compileContract() { local contract @@ -29,6 +31,9 @@ compileContract() { -o $CONTRACTS_DIR/solc/$PROJECT/$contract" $command + + # Copy the generated abi files to a single folder + cp "$CONTRACTS_DIR"/solc/$PROJECT/"$contract"/"$contract".sol/"$contract".abi.json "$ABI_DIR""$contract".abi } # Define optimization overrides in this function. Anything that is not an override will use the default value