diff --git a/.github/workflows/protocol-devchain-anvil.yml b/.github/workflows/protocol-devchain-anvil.yml new file mode 100644 index 00000000000..abe557ce4f7 --- /dev/null +++ b/.github/workflows/protocol-devchain-anvil.yml @@ -0,0 +1,126 @@ +name: Protocol Devchain Anvil +on: + push: + branches: + - master + +env: + # Increment these to force cache rebuilding + FOUNDRY_CACHE_KEY: 1 + +jobs: + build: + defaults: + run: + working-directory: packages/protocol + name: Generate anvil + runs-on: ["self-hosted", "org", "npm-publish"] + permissions: + contents: read + pull-requests: read + id-token: write + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Fail if there are test with wrong extension + run: | + if tree test-sol | grep -i ".sol" | grep -v ".sol"; then + echo "There are tests with wrong extensions" + tree test-sol | grep -i ".sol" | grep -v ".sol" + exit 1 + fi + - name: Foundry cache + id: foundry-cache + uses: actions/cache@v3 + with: + path: ./cache + key: ${{ runner.os }}-foundry-cache-${{ env.FOUNDRY_CACHE_KEY }} + - name: Foundry out + id: foundry-out + uses: actions/cache@v3 + with: + path: ./out + key: ${{ runner.os }}-foundry-out-${{ env.FOUNDRY_CACHE_KEY }} + + - name: Get Pull Request data + id: get_pr_data + uses: actions/github-script@v7 + with: + script: | + const result = ( + await github.rest.repos.listPullRequestsAssociatedWithCommit({ + commit_sha: context.sha, + owner: context.repo.owner, + repo: context.repo.repo, + }) + ).data[0]; + return result ? { number: result.number } : {}; + + - name: Set PR Number + id: set_pr_number + run: | + if [ -z "${{ steps.get_pr_data.outputs.number }}" ]; then + echo "PR_NUMBER=${{ github.event.pull_request.number }}" >> $GITHUB_ENV + else + echo "PR_NUMBER=${{ steps.get_pr_data.outputs.number }}" >> $GITHUB_ENV + fi + + - name: Display PR Number + run: | + echo "Pull Request Number: ${{ env.PR_NUMBER }}" + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + + - name: Install forge dependencies + run: forge install + + - name: Get current date + id: date + run: echo "::set-output name=date::$(date +'%Y-%m-%d')" + + - name: Generate migrations + run: ./migrations_sol/run_integration_tests_in_anvil.sh + + - name: Sanitize ref name + id: sanitize-ref-name + run: | + sanitized_ref_name=$(echo "${{ github.ref_name }}" | tr -cd '[:alnum:]-_') + echo "sanitized_ref_name=${sanitized_ref_name}" >> $GITHUB_ENV + + - name: Set package.json version based on GitHub ref + run: | + VERSION=${{ env.PR_NUMBER }} + echo "Setting version to 0.0.$VERSION" + jq ".version = \"0.0.$VERSION\"" .tmp/package.json > .tmp/temp.json && mv .tmp/temp.json .tmp/package.json + + - name: Upload devchain as artifact + uses: actions/upload-artifact@v4 + with: + name: devchain-${{ env.PR_NUMBER }}-${{ steps.date.outputs.date }} + path: packages/protocol/.tmp + # Max retention time is 90 days for public repos + # https://docs.github.com/en/actions/learn-github-actions/usage-limits-billing-and-administration#artifact-and-log-retention-policy + retention-days: 90 + + - name: Akeyless Get Secrets + id: get_auth_token + uses: docker://us-west1-docker.pkg.dev/devopsre/akeyless-public/akeyless-action:latest + with: + api-url: https://api.gateway.akeyless.celo-networks-dev.org + access-id: p-kf9vjzruht6l + static-secrets: '{"/static-secrets/NPM/npm-publish-token":"NPM_TOKEN"}' + + - uses: actions/setup-node@v4 + with: + node-version: '18.x' + registry-url: 'https://registry.npmjs.org' + + - name: Publish @celo/devchain-anvil + run: | + cat package.json + npm publish --access public + working-directory: packages/protocol/.tmp + env: + NODE_AUTH_TOKEN: ${{ env.NPM_TOKEN }} diff --git a/packages/protocol/migrations_sol/celo-anvil-README.md b/packages/protocol/migrations_sol/celo-anvil-README.md new file mode 100644 index 00000000000..46a9b59be67 --- /dev/null +++ b/packages/protocol/migrations_sol/celo-anvil-README.md @@ -0,0 +1,10 @@ +# celo devchain Anvil + +Anvil state with Celo core contracts for local testing and development. + +# Usage + +```bash +npm install --save-dev @celo/devchain-anvil +anvil --state +``` diff --git a/packages/protocol/migrations_sol/create_and_migrate_anvil_devchain.sh b/packages/protocol/migrations_sol/create_and_migrate_anvil_devchain.sh index dc49fc4af1f..8050b93c302 100755 --- a/packages/protocol/migrations_sol/create_and_migrate_anvil_devchain.sh +++ b/packages/protocol/migrations_sol/create_and_migrate_anvil_devchain.sh @@ -6,12 +6,19 @@ START_TIME=$SECONDS export ANVIL_PORT=8546 +echo "Forge version: $(forge --version)" + # TODO make this configurable FROM_ACCOUNT_NO_ZERO="f39Fd6e51aad88F6F4ce6aB8827279cffFb92266" # This is Anvil's default account (1) export FROM_ACCOUNT="0x$FROM_ACCOUNT_NO_ZERO" # Create temporary directory TEMP_FOLDER="$PWD/.tmp" +if [ -d "$TEMP_FOLDER" ]; then + # Remove temporary directory first it if exists + echo "Removing existing temporary folder..." + rm -rf $TEMP_FOLDER +fi mkdir -p $TEMP_FOLDER # Start a local anvil instance @@ -54,3 +61,6 @@ time forge script migrations_sol/Migration.s.sol --tc Migration --rpc-url http:/ # Keeping track of the finish time to measure how long it takes to run the script entirely ELAPSED_TIME=$(($SECONDS - $START_TIME)) echo "Total elapsed time: $ELAPSED_TIME seconds" +# Rename devchain artifact and remove unused directory +mv $TEMP_FOLDER/devchain/state.json $TEMP_FOLDER/devchain.json +rm -rf $TEMP_FOLDER/devchain diff --git a/packages/protocol/migrations_sol/start_anvil.sh b/packages/protocol/migrations_sol/start_anvil.sh index 2b64ee0c556..e75a82162b1 100755 --- a/packages/protocol/migrations_sol/start_anvil.sh +++ b/packages/protocol/migrations_sol/start_anvil.sh @@ -2,7 +2,15 @@ set -euo pipefail timestamp=`date -Iseconds` -ANVIL_FILE="$TEMP_FOLDER/anvil_state-$timestamp" +TMP_FOLDER="$PWD/.tmp" +ANVIL_FOLDER="$TMP_FOLDER/devchain" +mkdir -p $ANVIL_FOLDER +echo "Anvil state will be saved to $ANVIL_FOLDER" + +# create package.json +echo "{\"name\": \"@celo/devchain-anvil\",\"version\": \"1.0.0\",\"description\": \"Anvil based devchain that contains core smart contracts of celo\",\"author\":\"Celo\",\"license\": \"LGPL-3.0\"}" > $TMP_FOLDER/package.json + +cp $PWD/migrations_sol/celo-anvil-README.md $TMP_FOLDER/README.md if nc -z localhost $ANVIL_PORT; then echo "Port already used" @@ -10,9 +18,7 @@ if nc -z localhost $ANVIL_PORT; then echo "Killed previous Anvil" fi - - -anvil --port $ANVIL_PORT --gas-limit 50000000 --steps-tracing --code-size-limit 245760 --balance 60000 --dump-state $ANVIL_FILE & +anvil --port $ANVIL_PORT --gas-limit 50000000 --steps-tracing --code-size-limit 245760 --balance 60000 --dump-state $ANVIL_FOLDER --state-interval 1 & # alternatively: # ANVIL_PID=`lsof -i tcp:8545 | tail -n 1 | awk '{print $2}'` @@ -30,4 +36,4 @@ done cast rpc anvil_setLoggingEnabled true --rpc-url http://127.0.0.1:$ANVIL_PORT echo "Anvil launched" -sleep 1 \ No newline at end of file +sleep 1