Skip to content

Commit

Permalink
[docker] release aptos-node and aptos-indexer-grpc separately (#10664)
Browse files Browse the repository at this point in the history
  • Loading branch information
rustielin authored Oct 25, 2023
1 parent 441b0c8 commit 940f98a
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 3 deletions.
1 change: 1 addition & 0 deletions .github/workflows/copy-images-to-dockerhub-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ on:
- preview
tags:
- aptos-node-v*
- aptos-indexer-grpc-v*

permissions:
contents: read
Expand Down
58 changes: 55 additions & 3 deletions docker/release-images.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,29 @@
//
// Once you have all prerequisites fulfilled, you can run this script via:
// GIT_SHA=${{ github.sha }} GCP_DOCKER_ARTIFACT_REPO="${{ secrets.GCP_DOCKER_ARTIFACT_REPO }}" AWS_ACCOUNT_ID="${{ secrets.AWS_ECR_ACCOUNT_NUM }}" IMAGE_TAG_PREFIX="${{ inputs.image_tag_prefix }}" ./docker/release_images.sh --wait-for-image-seconds=1800
//
//
// You can also run this script locally with the DRY_RUN flag to test it out:
// IMAGE_TAG_PREFIX=devnet AWS_ACCOUNT_ID=bla GCP_DOCKER_ARTIFACT_REPO_US=bla GCP_DOCKER_ARTIFACT_REPO=bla GIT_SHA=bla ./docker/release-images.mjs --wait-for-image-seconds=3600 --dry-run
//

// When we release aptos-node, we also want to release related images for tooling, testing, etc. Similarly, other images have other related images
// that we can release together, ie in a release group.
const IMAGES_TO_RELEASE_BY_RELEASE_GROUP = {
"aptos-node": [
"validator",
"validator-testing",
"faucet",
"tools",
],
"aptos-indexer-grpc": [
"indexer-grpc",
],
}

const Features = {
Default: "default",
};

const IMAGES_TO_RELEASE_ONLY_INTERNAL = ["validator-testing"];
const IMAGES_TO_RELEASE = {
validator: {
Expand Down Expand Up @@ -88,7 +106,7 @@ execSync("pnpm install --frozen-lockfile", { stdio: "inherit" });
await import("zx/globals");

const REQUIRED_ARGS = ["GIT_SHA", "GCP_DOCKER_ARTIFACT_REPO", "GCP_DOCKER_ARTIFACT_REPO_US", "AWS_ACCOUNT_ID", "IMAGE_TAG_PREFIX"];
const OPTIONAL_ARGS = ["WAIT_FOR_IMAGE_SECONDS"];
const OPTIONAL_ARGS = ["WAIT_FOR_IMAGE_SECONDS", "DRY_RUN"];

const parsedArgs = {};

Expand Down Expand Up @@ -149,7 +167,23 @@ const ALL_TARGET_REGISTRIES = [
// default 10 seconds
parsedArgs.WAIT_FOR_IMAGE_SECONDS = parseInt(parsedArgs.WAIT_FOR_IMAGE_SECONDS ?? 10, 10);

for (const [image, imageConfig] of Object.entries(IMAGES_TO_RELEASE)) {
// dry run
console.log(`INFO: dry run: ${parsedArgs.DRY_RUN}`);

// get the appropriate release group based on the image tag prefix
const imageReleaseGroup = getImageReleaseGroupByImageTagPrefix(parsedArgs.IMAGE_TAG_PREFIX);
console.log(`INFO: image release group: ${imageReleaseGroup}`);

// only release the images that are part of the release group
const imageNamesToRelease = IMAGES_TO_RELEASE_BY_RELEASE_GROUP[imageReleaseGroup];
console.log(`INFO: image names to release: ${JSON.stringify(imageNamesToRelease)}`);

// iterate over all images to release, including their release configurations
const imagesToRelease = {};
for (const imageName of imageNamesToRelease) {
imagesToRelease[imageName] = IMAGES_TO_RELEASE[imageName];
}
for (const [image, imageConfig] of Object.entries(imagesToRelease)) {
for (const [profile, features] of Object.entries(imageConfig)) {
// build profiles that are not the default "release" will have a separate prefix
const profilePrefix = profile === "release" ? "" : profile;
Expand All @@ -165,6 +199,9 @@ for (const [image, imageConfig] of Object.entries(IMAGES_TO_RELEASE)) {
)}`;
const imageTarget = `${targetRegistry}/${image}:${joinTagSegments(parsedArgs.IMAGE_TAG_PREFIX, profilePrefix, featureSuffix)}`;
console.info(chalk.green(`INFO: copying ${imageSource} to ${imageTarget}`));
if (parsedArgs.DRY_RUN) {
continue;
}
await waitForImageToBecomeAvailable(imageSource, parsedArgs.WAIT_FOR_IMAGE_SECONDS);
await $`${crane} copy ${imageSource} ${imageTarget}`;
await $`${crane} copy ${imageSource} ${joinTagSegments(imageTarget, parsedArgs.GIT_SHA)}`;
Expand All @@ -178,6 +215,21 @@ function joinTagSegments(...segments) {
return segments.filter((s) => s).join("_");
}

// The image tag prefix is used to determine the release group. Examples:
// * tag a release as "aptos-node-vX.Y.Z"
// * tag a release as "aptos-indexer-grpc-vX.Y.Z"
function getImageReleaseGroupByImageTagPrefix(prefix) {
// iterate over the keys in IMAGES_TO_RELEASE_BY_RELEASE_GROUP
// if the prefix includes the release group, then return the release group
for (const [imageReleaseGroup, imagesToRelease] of Object.entries(IMAGES_TO_RELEASE_BY_RELEASE_GROUP)) {
if (prefix.includes(imageReleaseGroup)) {
return imageReleaseGroup;
}
}
// if there's no match, then release aptos-node by default
return "aptos-node";
}

async function waitForImageToBecomeAvailable(imageToWaitFor, waitForImageSeconds) {
const WAIT_TIME_IN_BETWEEN_ATTEMPTS = 10000; // 10 seconds in ms
const startTimeMs = Date.now();
Expand Down

0 comments on commit 940f98a

Please sign in to comment.