From dc2801b7ce86dff9c7b2d9afd7fcef8d9bdf4c4e Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Tue, 6 Feb 2024 09:58:07 -0800 Subject: [PATCH 01/10] chore: cleanup --- packages/synthetic-chain/upgrade-test-scripts/run_test.sh | 2 -- packages/synthetic-chain/upgrade-test-scripts/run_use.sh | 8 ++++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/synthetic-chain/upgrade-test-scripts/run_test.sh b/packages/synthetic-chain/upgrade-test-scripts/run_test.sh index 3034177e..2edf31cb 100755 --- a/packages/synthetic-chain/upgrade-test-scripts/run_test.sh +++ b/packages/synthetic-chain/upgrade-test-scripts/run_test.sh @@ -14,8 +14,6 @@ fi echo "[$PROPOSAL] Starting agd" -echo "[$PROPOSAL_PATH] Starting agd" - startAgd echo "[$PROPOSAL] Running test.sh." diff --git a/packages/synthetic-chain/upgrade-test-scripts/run_use.sh b/packages/synthetic-chain/upgrade-test-scripts/run_use.sh index 8001b8aa..237050d9 100755 --- a/packages/synthetic-chain/upgrade-test-scripts/run_use.sh +++ b/packages/synthetic-chain/upgrade-test-scripts/run_use.sh @@ -9,14 +9,14 @@ if [ -z "$PROPOSAL" ]; then echo "Must specify what proposal to use" exit 1 fi -PROPOSAL_PROPOSAL="/usr/src/proposals/$PROPOSAL/" +PROPOSAL_DIR="/usr/src/proposals/$PROPOSAL/" -if [ ! -d "$PROPOSAL_PROPOSAL" ]; then +if [ ! -d "$PROPOSAL_DIR" ]; then echo "Proposal $PROPOSAL does not exist" exit 1 fi -if [ ! -f "$PROPOSAL_PROPOSAL/use.sh" ]; then +if [ ! -f "$PROPOSAL_DIR/use.sh" ]; then echo "Proposal $PROPOSAL does not have a use.sh. Skipping." exit 0 fi @@ -27,7 +27,7 @@ echo "[$PROPOSAL] Starting agd in the background." startAgd echo "[$PROPOSAL] Agd started. Running use.sh." -cd "$PROPOSAL_PROPOSAL" +cd "$PROPOSAL_DIR" ./use.sh echo "[$PROPOSAL] Actions completed. Running for a few blocks and exiting." From 3588ad711b42e04bd7c22a6231b67b6d04684e92 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Tue, 6 Feb 2024 09:33:22 -0800 Subject: [PATCH 02/10] fix: yarn cache --- packages/synthetic-chain/src/cli/dockerfileGen.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/synthetic-chain/src/cli/dockerfileGen.ts b/packages/synthetic-chain/src/cli/dockerfileGen.ts index 13d89f55..058d3837 100755 --- a/packages/synthetic-chain/src/cli/dockerfileGen.ts +++ b/packages/synthetic-chain/src/cli/dockerfileGen.ts @@ -89,8 +89,7 @@ WORKDIR /usr/src/upgrade-test-scripts # base is a fresh sdk image so set up the proposal and its dependencies COPY --link --chmod=755 ./proposals/${proposalIdentifier}:${proposalName} /usr/src/proposals/${proposalIdentifier}:${proposalName} COPY --link --chmod=755 ./upgrade-test-scripts/env_setup.sh ./upgrade-test-scripts/start_to_to.sh ./upgrade-test-scripts/install_deps.sh /usr/src/upgrade-test-scripts/ -# XXX this hits the network each time because the fresh base lacks the global Yarn cache from the previous proposal's build -RUN ./install_deps.sh ${proposalIdentifier}:${proposalName} +RUN --mount=type=cache,target=/root/.yarn ./install_deps.sh ${proposalIdentifier}:${proposalName} COPY --link --from=prepare-${proposalName} /root/.agoric /root/.agoric From 06d6e5b9c89e5db9bad15207760f3c3ed4661d53 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Tue, 6 Feb 2024 11:19:56 -0800 Subject: [PATCH 03/10] refactor: run_execute out of start_to_to --- packages/synthetic-chain/src/cli/dockerfileGen.ts | 4 ++-- .../upgrade-test-scripts/run_execute.sh | 10 ++++++++++ .../upgrade-test-scripts/start_to_to.sh | 7 +++---- 3 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 packages/synthetic-chain/upgrade-test-scripts/run_execute.sh diff --git a/packages/synthetic-chain/src/cli/dockerfileGen.ts b/packages/synthetic-chain/src/cli/dockerfileGen.ts index 058d3837..1983b3ae 100755 --- a/packages/synthetic-chain/src/cli/dockerfileGen.ts +++ b/packages/synthetic-chain/src/cli/dockerfileGen.ts @@ -88,13 +88,13 @@ WORKDIR /usr/src/upgrade-test-scripts # base is a fresh sdk image so set up the proposal and its dependencies COPY --link --chmod=755 ./proposals/${proposalIdentifier}:${proposalName} /usr/src/proposals/${proposalIdentifier}:${proposalName} -COPY --link --chmod=755 ./upgrade-test-scripts/env_setup.sh ./upgrade-test-scripts/start_to_to.sh ./upgrade-test-scripts/install_deps.sh /usr/src/upgrade-test-scripts/ +COPY --link --chmod=755 ./upgrade-test-scripts/env_setup.sh ./upgrade-test-scripts/run_execute.sh ./upgrade-test-scripts/install_deps.sh /usr/src/upgrade-test-scripts/ RUN --mount=type=cache,target=/root/.yarn ./install_deps.sh ${proposalIdentifier}:${proposalName} COPY --link --from=prepare-${proposalName} /root/.agoric /root/.agoric SHELL ["/bin/bash", "-c"] -RUN ./start_to_to.sh +RUN ./run_execute.sh `; }, /** diff --git a/packages/synthetic-chain/upgrade-test-scripts/run_execute.sh b/packages/synthetic-chain/upgrade-test-scripts/run_execute.sh new file mode 100644 index 00000000..04afe84b --- /dev/null +++ b/packages/synthetic-chain/upgrade-test-scripts/run_execute.sh @@ -0,0 +1,10 @@ +#!/bin/bash +echo "Execute an upgrade" + +source ./env_setup.sh + +startAgd + +echo "Run several blocks for the upgrade to settle, then exit" +waitForBlock 5 +exit 0 diff --git a/packages/synthetic-chain/upgrade-test-scripts/start_to_to.sh b/packages/synthetic-chain/upgrade-test-scripts/start_to_to.sh index b6afe2a9..f69674ef 100755 --- a/packages/synthetic-chain/upgrade-test-scripts/start_to_to.sh +++ b/packages/synthetic-chain/upgrade-test-scripts/start_to_to.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Prepare or execute an upgrade +# Prepare an upgrade grep -qF 'env_setup.sh' /root/.bashrc || echo "source /usr/src/upgrade-test-scripts/env_setup.sh" >>/root/.bashrc grep -qF 'printKeys' /root/.bashrc || echo "printKeys" >>/root/.bashrc @@ -9,9 +9,8 @@ source ./env_setup.sh startAgd if [[ -z "${UPGRADE_TO}" ]]; then - echo "no upgrade set. running for a few blocks and exiting" - waitForBlock 5 - exit 0 + echo "Requires UPGRADE_TO to be set" + exit 1 fi voting_period_s=10 From 32346519ff098e8f5342b27ed666d1415ed56329 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Tue, 6 Feb 2024 11:31:27 -0800 Subject: [PATCH 04/10] refactor: use startAgd/killAgd in start_ag0 --- .../synthetic-chain/upgrade-test-scripts/start_ag0.sh | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/synthetic-chain/upgrade-test-scripts/start_ag0.sh b/packages/synthetic-chain/upgrade-test-scripts/start_ag0.sh index c3513180..59a5cc8f 100755 --- a/packages/synthetic-chain/upgrade-test-scripts/start_ag0.sh +++ b/packages/synthetic-chain/upgrade-test-scripts/start_ag0.sh @@ -1,7 +1,7 @@ #!/bin/bash # The name of the binary is an implementation detail. -agd () { +agd() { ag0 ${1+"$@"} } @@ -56,10 +56,7 @@ agd add-genesis-account "$GENACCT" "$coins" agd gentx validator 5000000000ubld --keyring-backend="test" --chain-id "$CHAINID" agd collect-gentxs -agd start --log_level warn & -agd_PID=$! -wait_for_bootstrap -waitForBlock 2 +startAgd voting_period_s=10 latest_height=$(agd status | jq -r .SyncInfo.latest_block_height) @@ -94,5 +91,5 @@ while true; do sleep 1 done -kill $agd_PID +killAgd echo "state directory $HOME/.agoric ready for upgrade to $UPGRADE_TO" From 3639158ac7ac1e5fd1dd28e0087176ddd2e5fb2c Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Tue, 6 Feb 2024 11:41:01 -0800 Subject: [PATCH 05/10] refactor: 'run' for scripts that terminate --- packages/synthetic-chain/src/cli/dockerfileGen.ts | 15 +++++++++------ .../upgrade-test-scripts/env_setup.sh | 9 +++------ .../upgrade-test-scripts/run_execute.sh | 2 +- .../{start_to_to.sh => run_prepare.sh} | 0 .../{start_ag0.sh => run_prepare_zero.sh} | 1 + 5 files changed, 14 insertions(+), 13 deletions(-) rename packages/synthetic-chain/upgrade-test-scripts/{start_to_to.sh => run_prepare.sh} (100%) rename packages/synthetic-chain/upgrade-test-scripts/{start_ag0.sh => run_prepare_zero.sh} (99%) diff --git a/packages/synthetic-chain/src/cli/dockerfileGen.ts b/packages/synthetic-chain/src/cli/dockerfileGen.ts index 1983b3ae..ff721a63 100755 --- a/packages/synthetic-chain/src/cli/dockerfileGen.ts +++ b/packages/synthetic-chain/src/cli/dockerfileGen.ts @@ -17,9 +17,9 @@ import { */ const stage = { /** - * ag0, start of the chain + * Prepare an upgrade from ag0, start of the chain */ - START(proposalName: string, to: string) { + PREPARE_ZERO(proposalName: string, to: string) { const agZeroUpgrade = 'agoric-upgrade-7-2'; return ` ## START @@ -30,10 +30,10 @@ ENV UPGRADE_TO=${to} # put env functions into shell environment RUN echo '. /usr/src/upgrade-test-scripts/env_setup.sh' >> ~/.bashrc -COPY --link --chmod=755 ./upgrade-test-scripts/env_setup.sh ./upgrade-test-scripts/start_ag0.sh /usr/src/upgrade-test-scripts/ +COPY --link --chmod=755 ./upgrade-test-scripts/env_setup.sh ./upgrade-test-scripts/run_prepare_zero.sh /usr/src/upgrade-test-scripts/ SHELL ["/bin/bash", "-c"] # this is the only layer that starts ag0 -RUN /usr/src/upgrade-test-scripts/start_ag0.sh +RUN /usr/src/upgrade-test-scripts/run_prepare_zero.sh `; }, /** @@ -65,9 +65,10 @@ ENV UPGRADE_TO=${planName} UPGRADE_INFO=${JSON.stringify( encodeUpgradeInfo(upgradeInfo), )} +COPY --link --chmod=755 ./upgrade-test-scripts/env_setup.sh ./upgrade-test-scripts/run_prepare.sh /usr/src/upgrade-test-scripts/ WORKDIR /usr/src/upgrade-test-scripts SHELL ["/bin/bash", "-c"] -RUN ./start_to_to.sh +RUN ./run_prepare.sh `; }, /** @@ -230,7 +231,9 @@ export function writeDockerfile( if (previousProposal) { blocks.push(stage.PREPARE(proposal, previousProposal)); } else { - blocks.push(stage.START(proposal.proposalName, proposal.planName)); + blocks.push( + stage.PREPARE_ZERO(proposal.proposalName, proposal.planName), + ); } blocks.push(stage.EXECUTE(proposal)); break; diff --git a/packages/synthetic-chain/upgrade-test-scripts/env_setup.sh b/packages/synthetic-chain/upgrade-test-scripts/env_setup.sh index d718fe33..9dec7e69 100755 --- a/packages/synthetic-chain/upgrade-test-scripts/env_setup.sh +++ b/packages/synthetic-chain/upgrade-test-scripts/env_setup.sh @@ -61,7 +61,8 @@ if [[ "$binary" == "agd" ]]; then fi startAgd() { - echo "Starting agd in background" + echo "startAgd()" + agd start --log_level warn "$@" & AGD_PID=$! echo $AGD_PID >$HOME/.agoric/agd.pid @@ -70,17 +71,13 @@ startAgd() { } killAgd() { + echo "killAgd()" AGD_PID=$(cat $HOME/.agoric/agd.pid) kill $AGD_PID rm $HOME/.agoric/agd.pid wait $AGD_PID || true } -waitAgd() { - wait $(cat $HOME/.agoric/agd.pid) - rm $HOME/.agoric/agd.pid -} - provisionSmartWallet() { addr="$1" amount="$2" diff --git a/packages/synthetic-chain/upgrade-test-scripts/run_execute.sh b/packages/synthetic-chain/upgrade-test-scripts/run_execute.sh index 04afe84b..a6acbf06 100644 --- a/packages/synthetic-chain/upgrade-test-scripts/run_execute.sh +++ b/packages/synthetic-chain/upgrade-test-scripts/run_execute.sh @@ -7,4 +7,4 @@ startAgd echo "Run several blocks for the upgrade to settle, then exit" waitForBlock 5 -exit 0 +killAgd diff --git a/packages/synthetic-chain/upgrade-test-scripts/start_to_to.sh b/packages/synthetic-chain/upgrade-test-scripts/run_prepare.sh similarity index 100% rename from packages/synthetic-chain/upgrade-test-scripts/start_to_to.sh rename to packages/synthetic-chain/upgrade-test-scripts/run_prepare.sh diff --git a/packages/synthetic-chain/upgrade-test-scripts/start_ag0.sh b/packages/synthetic-chain/upgrade-test-scripts/run_prepare_zero.sh similarity index 99% rename from packages/synthetic-chain/upgrade-test-scripts/start_ag0.sh rename to packages/synthetic-chain/upgrade-test-scripts/run_prepare_zero.sh index 59a5cc8f..7154d92e 100755 --- a/packages/synthetic-chain/upgrade-test-scripts/start_ag0.sh +++ b/packages/synthetic-chain/upgrade-test-scripts/run_prepare_zero.sh @@ -1,4 +1,5 @@ #!/bin/bash +# Prepare an upgrade from ag0 # The name of the binary is an implementation detail. agd() { From 2b32b03a72859cc291c8b9780f5005e65eca9c39 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Fri, 2 Feb 2024 16:10:58 -0800 Subject: [PATCH 06/10] ci: remote multiplatform builder --- .github/workflows/ci.yml | 161 ++++-------------- depot.json | 1 + package.json | 6 +- packages/synthetic-chain/cli.ts | 25 ++- packages/synthetic-chain/docker-bake.hcl | 3 + packages/synthetic-chain/src/cli/build.ts | 5 +- .../synthetic-chain/src/cli/dockerfileGen.ts | 10 +- 7 files changed, 72 insertions(+), 139 deletions(-) create mode 100644 depot.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7f42b615..64ce9041 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,40 +32,20 @@ concurrency: env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} - # Name these so they look less similar than AMD/ARM; omit 64 as uninformative. - X86_PLATFORM: linux/amd64 - ARM_PLATFORM: linux/arm64/v8 jobs: - platforms: - runs-on: ubuntu-latest - outputs: - platforms: '${{ steps.platforms.outputs.platforms }}' - steps: - - name: Compute Docker platforms - id: platforms - run: | - if ${{ github.event_name == 'pull_request' || github.event_name == 'merge_group' }}; then - # JSON-encoded list consisting only of the default platform. - platforms='["'"$X86_PLATFORM"'"]' - else - platforms='["$X86_PLATFORM","$ARM_PLATFORM"]' - fi - echo "platforms=$platforms" >> $GITHUB_OUTPUT - # see https://docs.docker.com/build/ci/github-actions/test-before-push/ test-proposals: - needs: [platforms] - # UNTIL https://github.com/Agoric/agoric-3-proposals/issues/2 - timeout-minutes: 120 - strategy: - matrix: - platform: ${{ fromJSON(needs.platforms.outputs.platforms) }} - # Run on our own self-hosted ARM64 machine if the platform is ARMish. - runs-on: ${{ contains(matrix.platform, '/arm') && fromJSON('["self-hosted","Linux","ARM64"]') || 'ubuntu-latest' }} + permissions: + # allow issuing OIDC tokens for this workflow run + id-token: write + # allow at least reading the repo contents, add other permissions if necessary + contents: read + # to push the resulting images + packages: write + runs-on: 'ubuntu-latest' steps: - name: free up disk space - if: ${{ !contains(matrix.platform, '/arm') }} run: | # Workaround to provide additional free space for testing. # https://github.com/actions/runner-images/issues/2840#issuecomment-790492173 @@ -82,11 +62,12 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + - uses: depot/setup-action@v1 + with: + oidc: true # to set DEPOT_TOKEN for later steps - - name: Set up QEMU for cross-platform builds - uses: docker/setup-qemu-action@v3 + # make Docker's CLI use depot to build + - run: depot configure-docker - name: Log in to the Container registry uses: docker/login-action@v3 @@ -102,24 +83,6 @@ jobs: with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - - name: Compute Docker tags - id: docker-tags - run: | - sep= - # A list of comma-separated tags to merge in the final image. - SUFFIXED= - # Our platform, replacing slashes with underscores. - uarch=$(echo "${{ matrix.platform }}" | tr / _) - for TAG in ${{ steps.meta.outputs.tags }}; do - SUFFIXED="$SUFFIXED$sep$TAG-$uarch" - if test -z "$sep"; then - # The first tag (suffixed with our architecture) is the one we build. - sep=, - echo "tag=$TAG-$uarch" | tee -a $GITHUB_OUTPUT - fi - done - echo "tags=$SUFFIXED" | tee -a $GITHUB_OUTPUT - - name: Setup synthetic-chain run: | # The .ts scripts depend upon this @@ -127,26 +90,28 @@ jobs: # Enable corepack for packageManager config corepack enable || sudo corepack enable yarn install + # prepare files for bake-action + tsx packages/synthetic-chain prepare-build - - run: docker system df - - run: docker buildx du --verbose - - run: df -h + # Verify that all "use" images build across platforms. + - name: Build proposal "use" images + uses: depot/bake-action@v1 + with: + files: | + ./docker-bake.json + ./docker-bake.hcl + ${{ steps.meta.outputs.bake-file }} + targets: use - # Test before pushing the images. + # Verify that proposals' tests pass. + # Note this builds each proposal testing image sequentially. It does that so it can delete the image + # after it passees, freeing up disk space. - name: Build and run proposal tests - if: ${{ matrix.platform == env.X86_PLATFORM }} run: yarn test - - run: docker system df - - run: docker buildx du --verbose - - run: df -h - - # Build a "use" image for each proposal. This uses Docker Bake's - # matrix feature. We could have each "use" image built in a different runner - # by including https://github.com/docker/bake-action?tab=readme-ov-file#list-targets - # in the GHA matrix, but that wouldn't be able to resolve the DAG of what to build first. + # Push the images if the tests pass and this is not a PR - name: Push proposal "use" images - uses: docker/bake-action@v4 + uses: depot/bake-action@v1 # If we pushed from PRs, each one would overwrite main's (e.g. use-upgrade-8) # To push PR "use" images we'll need to qualify the tag (e.g. use-upgrade-8-pr-2). if: ${{ github.event_name != 'pull_request' }} @@ -156,75 +121,7 @@ jobs: ./docker-bake.hcl ${{ steps.meta.outputs.bake-file }} targets: use - - - run: docker system df - - run: docker buildx du --verbose - - run: df -h - - - name: Build and push default image - uses: docker/build-push-action@v5 - with: - context: . - platforms: ${{ matrix.platform }} - # push to registry on every repo push. A PR #2 will push with tag `pr-2` and `main` will have tag `main`. - # See https://github.com/docker/metadata-action?tab=readme-ov-file#basic. push: true - tags: ${{ steps.docker-tags.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - - - run: docker system df - - run: docker buildx du --verbose - - run: df -h - - # Merge the default image from each platform into one multi-arch image, - # then publish that multiarch image. - docker-publish-multiarch: - needs: [test-proposals, platforms] - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - with: - buildkitd-flags: --debug - - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - - - name: Log in to the Container registry - uses: docker/login-action@v3 - with: - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - registry: ${{ env.REGISTRY }} - - name: Compute tags - id: docker-tags - run: | - echo "tags=${{ steps.meta.outputs.tags }}" >> $GITHUB_OUTPUT - - - name: Push multiarch image - run: | - set -ex - # Push all tags, comprised of all architectures, to the registry. - for TAG in ${{ steps.docker-tags.outputs.tags }}; do - sources= - for ARCH in ${{ join(fromJson(needs.platforms.outputs.platforms), ' ') }}; do - uarch=$(echo "$ARCH" | tr / _) - BUILD_TAG="$TAG-$uarch" - sources="$sources $BUILD_TAG" - done - docker buildx imagetools create --tag "$TAG"$sources - done - name: notify on failure if: failure() && github.event_name != 'pull_request' diff --git a/depot.json b/depot.json new file mode 100644 index 00000000..591f93f8 --- /dev/null +++ b/depot.json @@ -0,0 +1 @@ +{"id":"bqgtmlhmh8"} diff --git a/package.json b/package.json index 650a4c03..70025d6f 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,11 @@ "@agoric/synthetic-chain": "workspace:*" }, "agoricSyntheticChain": { - "fromTag": null + "fromTag": null, + "platforms": [ + "linux/amd64", + "linux/arm64" + ] }, "license": "Apache-2.0", "packageManager": "yarn@4.0.2", diff --git a/packages/synthetic-chain/cli.ts b/packages/synthetic-chain/cli.ts index 62882649..a1e3d257 100755 --- a/packages/synthetic-chain/cli.ts +++ b/packages/synthetic-chain/cli.ts @@ -41,7 +41,9 @@ const proposals = match const [cmd] = positionals; // TODO consider a lib like Commander for auto-gen help -const usage = `USAGE: +const USAGE = `USAGE: +prepare-build - generate Docker build configs + build - build the synthetic-chain "use" images test [--debug] - build the "test" images and run them @@ -50,6 +52,15 @@ test -m - target a particular proposal by substring match doctor - diagnostics and quick fixes `; +const EXPLAIN_MULTIPLATFORM = ` +ERROR: docker exporter does not currently support exporting manifest lists + +Multiple platforms are configured but Docker does not support multiplatform in one builder. +Until https://github.com/docker/roadmap/issues/371, attempting it will error as above. + +Instead use a builder that supports multiplatform such as depot.dev. +`; + /** * Put into places files that building depends upon. */ @@ -58,7 +69,7 @@ const prepareDockerBuild = () => { // copy and generate files of the build context that aren't in the build contents execSync(`cp -r ${path.resolve(cliPath, '..', 'docker-bake.hcl')} .`); writeDockerfile(allProposals, buildConfig.fromTag); - writeBakefileProposals(allProposals); + writeBakefileProposals(allProposals, buildConfig.platforms); // copy and generate files to include in the build execSync(`cp -r ${path.resolve(cliPath, '..', 'upgrade-test-scripts')} .`); buildProposalSubmissions(proposals); @@ -70,8 +81,16 @@ const prepareDockerBuild = () => { }; switch (cmd) { + case 'prepare-build': + prepareDockerBuild(); + break; case 'build': { prepareDockerBuild(); + // do not encapsulate running Depot. It's a special case which the user should understand. + if (buildConfig.platforms) { + console.error(EXPLAIN_MULTIPLATFORM); + process.exit(1); + } bakeTarget('use', values.dry); break; } @@ -103,5 +122,5 @@ switch (cmd) { runDoctor(allProposals); break; default: - console.log(usage); + console.log(USAGE); } diff --git a/packages/synthetic-chain/docker-bake.hcl b/packages/synthetic-chain/docker-bake.hcl index 75f2e728..17358f35 100644 --- a/packages/synthetic-chain/docker-bake.hcl +++ b/packages/synthetic-chain/docker-bake.hcl @@ -14,9 +14,11 @@ group "default" { ] } +// Images to use the result of all local proposals, optionally built multi-platform target "use" { inherits = ["docker-metadata-action"] name = "use-${proposal}" + platforms = PLATFORMS matrix = { proposal = PROPOSALS } @@ -29,6 +31,7 @@ target "use" { target = "use-${proposal}" } +// Image to test the result of a proposal, always current platform target "test" { name = "test-${proposal}" matrix = { diff --git a/packages/synthetic-chain/src/cli/build.ts b/packages/synthetic-chain/src/cli/build.ts index 3b0570a4..6d7aebaf 100755 --- a/packages/synthetic-chain/src/cli/build.ts +++ b/packages/synthetic-chain/src/cli/build.ts @@ -3,6 +3,8 @@ import fs from 'node:fs'; import path from 'node:path'; import { ProposalInfo } from './proposals.js'; +export type Platform = 'linux/amd64' | 'linux/arm64'; + export type AgoricSyntheticChainConfig = { /** * The agoric-3-proposals tag to build the agoric synthetic chain from. @@ -10,6 +12,7 @@ export type AgoricSyntheticChainConfig = { * Defaults to `main`, which containing all passed proposals */ fromTag: string | null; + platforms?: Platform[]; }; const defaultConfig: AgoricSyntheticChainConfig = { @@ -66,7 +69,7 @@ export const buildProposalSubmissions = (proposals: ProposalInfo[]) => { /** * Bake images using the docker buildx bake command. - * + * * Note this uses `--load` which pushes the completed images to the builder, * consuming 2-3 GB per image. * @see {@link https://docs.docker.com/engine/reference/commandline/buildx_build/#load} diff --git a/packages/synthetic-chain/src/cli/dockerfileGen.ts b/packages/synthetic-chain/src/cli/dockerfileGen.ts index ff721a63..a3c2f2ef 100755 --- a/packages/synthetic-chain/src/cli/dockerfileGen.ts +++ b/packages/synthetic-chain/src/cli/dockerfileGen.ts @@ -3,7 +3,6 @@ import fs from 'node:fs'; import { - lastPassedProposal, type CoreEvalProposal, type ProposalInfo, type SoftwareUpgradeProposal, @@ -11,6 +10,7 @@ import { imageNameForProposal, isPassed, } from './proposals.js'; +import { Platform } from './build.ts'; /** * Templates for Dockerfile stages @@ -183,9 +183,15 @@ ENTRYPOINT ./start_agd.sh }, }; -export function writeBakefileProposals(allProposals: ProposalInfo[]) { +export function writeBakefileProposals( + allProposals: ProposalInfo[], + platforms?: Platform[], +) { const json = { variable: { + PLATFORMS: { + default: platforms || null, + }, PROPOSALS: { default: allProposals.map(p => p.proposalName), }, From 4cf6ff44759508ddeb8ad840ff28385e5869c7cc Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Tue, 6 Feb 2024 13:23:31 -0800 Subject: [PATCH 07/10] test(upgrade-10): reduce wait --- proposals/34:upgrade-10/pre.test.js | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/proposals/34:upgrade-10/pre.test.js b/proposals/34:upgrade-10/pre.test.js index 75677b3d..1cc91fbc 100644 --- a/proposals/34:upgrade-10/pre.test.js +++ b/proposals/34:upgrade-10/pre.test.js @@ -4,10 +4,11 @@ import { promises as fs } from 'fs'; import { agd, - agoric, agops, + agoric, } from '@agoric/synthetic-chain/src/lib/cliHelper.js'; +import { getUser } from '@agoric/synthetic-chain/src/lib/commonUpgradeHelpers.js'; import { GOV1ADDR, GOV2ADDR, @@ -15,16 +16,6 @@ import { PSM_PAIR, } from '@agoric/synthetic-chain/src/lib/constants.js'; import { openVault } from '@agoric/synthetic-chain/src/lib/econHelpers.js'; -import { - getUser, - waitForBlock, -} from '@agoric/synthetic-chain/src/lib/commonUpgradeHelpers.js'; - -test.before(async () => { - console.log('Wait for upgrade to settle'); - - await waitForBlock(20); -}); test(`Ensure there's only uist`, async t => { const result = await agd.query( From 879ceab89fe7107202c731a0d502aba6255549d6 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Tue, 6 Feb 2024 14:40:11 -0800 Subject: [PATCH 08/10] test: large stage start log message --- .../upgrade-test-scripts/run_execute.sh | 13 ++++++++++- .../upgrade-test-scripts/run_prepare.sh | 22 ++++++++++++++----- .../upgrade-test-scripts/run_test.sh | 19 +++++++++++++--- .../upgrade-test-scripts/run_use.sh | 11 ++++++++++ 4 files changed, 56 insertions(+), 9 deletions(-) diff --git a/packages/synthetic-chain/upgrade-test-scripts/run_execute.sh b/packages/synthetic-chain/upgrade-test-scripts/run_execute.sh index a6acbf06..102d2dbb 100644 --- a/packages/synthetic-chain/upgrade-test-scripts/run_execute.sh +++ b/packages/synthetic-chain/upgrade-test-scripts/run_execute.sh @@ -1,5 +1,16 @@ #!/bin/bash -echo "Execute an upgrade" + +# figlet -f cyberlarge Execute upgrade +echo -e ' + _______ _ _ _______ _______ _ _ _______ _______ + |______ \___/ |______ | | | | |______ + |______ _/ \_ |______ |_____ |_____| | |______ + + _ _ _____ ______ ______ _______ ______ _______ + | | |_____] | ____ |_____/ |_____| | \ |______ + |_____| | |_____| | \_ | | |_____/ |______ +' +echo "Execute the upgrade in consensus" source ./env_setup.sh diff --git a/packages/synthetic-chain/upgrade-test-scripts/run_prepare.sh b/packages/synthetic-chain/upgrade-test-scripts/run_prepare.sh index f69674ef..31b5d436 100755 --- a/packages/synthetic-chain/upgrade-test-scripts/run_prepare.sh +++ b/packages/synthetic-chain/upgrade-test-scripts/run_prepare.sh @@ -1,6 +1,23 @@ #!/bin/bash # Prepare an upgrade +if [[ -z "${UPGRADE_TO}" ]]; then + echo "Requires UPGRADE_TO to be set" + exit 1 +fi + +# figlet -f cyberlarge Prepare upgrade +echo -e ' + _____ ______ _______ _____ _______ ______ _______ + |_____] |_____/ |______ |_____] |_____| |_____/ |______ + | | \_ |______ | | | | \_ |______ + + _ _ _____ ______ ______ _______ ______ _______ + | | |_____] | ____ |_____/ |_____| | \ |______ + |_____| | |_____| | \_ | | |_____/ |______ +' +echo "Preparing an upgrade to $UPGRADE_TO" + grep -qF 'env_setup.sh' /root/.bashrc || echo "source /usr/src/upgrade-test-scripts/env_setup.sh" >>/root/.bashrc grep -qF 'printKeys' /root/.bashrc || echo "printKeys" >>/root/.bashrc @@ -8,11 +25,6 @@ source ./env_setup.sh startAgd -if [[ -z "${UPGRADE_TO}" ]]; then - echo "Requires UPGRADE_TO to be set" - exit 1 -fi - voting_period_s=10 latest_height=$(agd status | jq -r .SyncInfo.latest_block_height) height=$((latest_height + voting_period_s + 20)) diff --git a/packages/synthetic-chain/upgrade-test-scripts/run_test.sh b/packages/synthetic-chain/upgrade-test-scripts/run_test.sh index 2edf31cb..4a1b5bef 100755 --- a/packages/synthetic-chain/upgrade-test-scripts/run_test.sh +++ b/packages/synthetic-chain/upgrade-test-scripts/run_test.sh @@ -3,17 +3,30 @@ # Note that STDOUT mixes the two. TODO separate them cleanly with log output. set -e - -source ./env_setup.sh - PROPOSAL=$1 if [ -z "$PROPOSAL" ]; then echo "Must specify what proposal to use" exit 1 fi +# figlet -f cyberlarge Test proposal outcome +echo ' + _______ _______ _______ _______ + | |______ |______ | + | |______ ______| | + + _____ ______ _____ _____ _____ _______ _______ + |_____] |_____/ | | |_____] | | |______ |_____| | + | | \_ |_____| | |_____| ______| | | |_____ + + _____ _ _ _______ _______ _____ _______ _______ + | | | | | | | | | | | |______ + |_____| |_____| | |_____ |_____| | | | |______ +' + echo "[$PROPOSAL] Starting agd" +source ./env_setup.sh startAgd echo "[$PROPOSAL] Running test.sh." diff --git a/packages/synthetic-chain/upgrade-test-scripts/run_use.sh b/packages/synthetic-chain/upgrade-test-scripts/run_use.sh index 237050d9..f7604262 100755 --- a/packages/synthetic-chain/upgrade-test-scripts/run_use.sh +++ b/packages/synthetic-chain/upgrade-test-scripts/run_use.sh @@ -21,6 +21,17 @@ if [ ! -f "$PROPOSAL_DIR/use.sh" ]; then exit 0 fi +# figlet -f cyberlarge Use proposal +echo ' + _ _ _______ _______ + | | |______ |______ + |_____| ______| |______ + + _____ ______ _____ _____ _____ _______ _______ + |_____] |_____/ | | |_____] | | |______ |_____| | + | | \_ |_____| | |_____| ______| | | |_____ +' + source ./env_setup.sh echo "[$PROPOSAL] Starting agd in the background." From 424e8f4d3e82d6592a00aa82d286c3c89bd31d17 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Tue, 6 Feb 2024 14:53:39 -0800 Subject: [PATCH 09/10] feat: colored log for each test start --- packages/synthetic-chain/cli.ts | 3 +++ packages/synthetic-chain/package.json | 1 + yarn.lock | 3 ++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/synthetic-chain/cli.ts b/packages/synthetic-chain/cli.ts index a1e3d257..78146a94 100755 --- a/packages/synthetic-chain/cli.ts +++ b/packages/synthetic-chain/cli.ts @@ -3,6 +3,7 @@ import { execSync } from 'node:child_process'; import path from 'node:path'; import { parseArgs } from 'node:util'; +import chalk from 'chalk'; import { bakeTarget, buildProposalSubmissions, @@ -101,12 +102,14 @@ switch (cmd) { if (values.debug) { const proposal = matchOneProposal(proposals, match!); + console.log(chalk.yellow.bold(`Debugging ${proposal.proposalName}`)); bakeTarget(imageNameForProposal(proposal, 'test').target, values.dry); debugTestImage(proposal); // don't bother to delete the test image because there's just one // and the user probably wants to run it again. } else { for (const proposal of proposals) { + console.log(chalk.cyan.bold(`Testing ${proposal.proposalName}`)); const image = imageNameForProposal(proposal, 'test'); bakeTarget(image.target, values.dry); runTestImage(proposal); diff --git a/packages/synthetic-chain/package.json b/packages/synthetic-chain/package.json index 4c558e62..3e08db1b 100644 --- a/packages/synthetic-chain/package.json +++ b/packages/synthetic-chain/package.json @@ -20,6 +20,7 @@ "dependencies": { "@endo/zip": "^1.0.0", "better-sqlite3": "^9.2.2", + "chalk": "^5.3.0", "execa": "^8.0.1", "tsx": "^3.12.8", "typescript": "^5.3.3" diff --git a/yarn.lock b/yarn.lock index bd78edcb..4b1673e7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13,6 +13,7 @@ __metadata: "@types/node": "npm:^18.11.9" ava: "npm:^5.3.0" better-sqlite3: "npm:^9.2.2" + chalk: "npm:^5.3.0" execa: "npm:^8.0.1" tsx: "npm:^3.12.8" typescript: "npm:^5.3.3" @@ -571,7 +572,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^5.2.0": +"chalk@npm:^5.2.0, chalk@npm:^5.3.0": version: 5.3.0 resolution: "chalk@npm:5.3.0" checksum: 8297d436b2c0f95801103ff2ef67268d362021b8210daf8ddbe349695333eb3610a71122172ff3b0272f1ef2cf7cc2c41fdaa4715f52e49ffe04c56340feed09 From 40580b2b0c8ed37a15a9e8c1306cea4b0f86c043 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Tue, 6 Feb 2024 15:49:57 -0800 Subject: [PATCH 10/10] test(crabble): robustness --- .../64:crabble-start/test-crabble-start.js | 48 +++++++++++-------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/proposals/64:crabble-start/test-crabble-start.js b/proposals/64:crabble-start/test-crabble-start.js index 0814aa80..800106d2 100644 --- a/proposals/64:crabble-start/test-crabble-start.js +++ b/proposals/64:crabble-start/test-crabble-start.js @@ -222,6 +222,20 @@ const readBundleSizes = async src => { return { bundleSizes, totalSize }; }; +const minute = 60 / 1; // block time is ~1sec + +/** + * @param {() => Promise} check + */ +const poll = async (check, maxTries) => { + for (let tries = 0; tries < maxTries; tries += 1) { + const ok = await check(); + if (ok) return; + await waitForBlock(); + } + throw Error(`tried ${maxTries} times without success`); +}; + test.serial('ensure enough IST to install bundles', async t => { const { agd, config, src } = t.context; const { totalSize, bundleSizes } = await readBundleSizes(src); @@ -277,6 +291,7 @@ test.serial('core eval prereqs: provision royalty, gov, ...', async t => { const { agd, config } = t.context; const { entries } = Object; + console.log('Adding keys, expect errors...'); for (const [name, { address, mnemonic }] of entries(config.accounts)) { try { agd.lookup(address); @@ -287,6 +302,7 @@ test.serial('core eval prereqs: provision royalty, gov, ...', async t => { agd.keys.add(name, mnemonic); } + console.log('Checking wallet state in vstorage'); for (const [name, { address }] of entries(config.accounts)) { const walletPath = `published.wallet.${address}`; const data = await agd.query(['vstorage', 'data', walletPath]); @@ -386,18 +402,6 @@ test.serial(`agoricNames.instance is populated`, async t => { const { config, agoric, agd } = t.context; const { instance: target } = config; - /** - * @param {() => Promise} check - */ - const poll = async (check, maxTries) => { - for (let tries = 0; tries < maxTries; tries += 1) { - const ok = await check(); - if (ok) return; - await waitForBlock(); - } - throw Error(`tried ${maxTries} times without success`); - }; - const checkForInstance = async () => { const { instance } = await wellKnownIdentities({ agoric }); const present = Object.keys(instance); @@ -405,7 +409,6 @@ test.serial(`agoricNames.instance is populated`, async t => { }; // contract initialization took ~10min in mainnet - const minute = 60 / 1; // block time is ~1sec poll(checkForInstance, 15 * minute); t.pass(); }); @@ -423,13 +426,18 @@ test.serial(`agoricNames.instance is populated`, async t => { // // a latestQuestion node published. test.serial('crabble governance is present', async t => { const { agd } = t.context; - const { children } = await agd.query([ - 'vstorage', - 'children', - 'published.crabble', - ]); - console.log({ children }); - testIncludes(t, 'governance', children, 'crabble committee'); + const checkForGovernance = async () => { + const { children } = await agd.query([ + 'vstorage', + 'children', + 'published.crabble', + ]); + console.log({ children }); + return children.includes('governance'); + }; + // contract initialization took ~10min in mainnet + poll(checkForGovernance, 15 * minute); + t.pass(); }); // // test.todo('test contract features- mint character');