Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[docker] release aptos-node and aptos-indexer-grpc separately #10664

Merged
merged 1 commit into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading