Skip to content

Commit

Permalink
Merge branch 'main' into addcognitotopep
Browse files Browse the repository at this point in the history
  • Loading branch information
heliuchuan authored Sep 26, 2024
2 parents 2d2513f + 5ad601c commit a033436
Show file tree
Hide file tree
Showing 7 changed files with 525 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
name: "Determine or Use Target Branch and Get Latest Docker Image"
description: |
Determine the branch to fetch the latest docker image tag from, or use a target branch directly.
- If base-branch is set, determine the target branch to fetch the latest docker image tag from
- Determine the IMAGE_TAG based on the latest release R and check for images built on branch R - 1:
- For commits on the aptos-release-v1.19 branch, the IMAGE_TAG should be the latest commit built on aptos-release-v1.18
- For commits on the main branch, the IMAGE_TAG should be the latest commit on the max release aptos-release-v<X.X> branch
- For commits on other branches, the IMAGE_TAG should be the latest commit on the branch's last release aptos-release-v<X.X> branch
- If branch is set, use it directly
inputs:
base-branch:
description: "The base branch to determine the target from, or use a target branch directly"
required: false
branch:
description: "Use this branch directly if set"
required: false
variants:
description: "The variants to check, as a space-separated string, e.g. 'performance failpoints'"
required: false

outputs:
TARGET_BRANCH:
description: "The determined or target target branch"
value: ${{ steps.set-target-branch.outputs.TARGET_BRANCH }}
IMAGE_TAG:
description: "The latest docker image tag for the given branch and variants"
value: ${{ steps.determine-test-image-tag.outputs.IMAGE_TAG }}

runs:
using: composite
steps:
# Checkout repository based on base branch or target branch
- name: Checkout branch
uses: actions/checkout@v4
with:
ref: ${{ inputs.base-branch || inputs.branch }}
path: checkout_branch
fetch-depth: 0

- name: Setup Python environment
uses: ./checkout_branch/.github/actions/python-setup
with:
pyproject_directory: checkout_branch/testsuite

# Determine the target branch if base-branch is used
- name: Set target branch
id: set-target-branch
run: |
if [[ -n "${{ inputs.base-branch }}" ]]; then
base_branch="${{ inputs.base-branch }}"
echo "Determining target branch from base branch: $base_branch"
./testrun determine_target_branch_to_fetch_last_released_image.py "$base_branch"
else
echo "Using target branch: ${{ inputs.branch }}"
echo "TARGET_BRANCH=${{ inputs.branch }}" >> $GITHUB_OUTPUT
fi
shell: bash
working-directory: checkout_branch/testsuite

# Checkout the determined or target branch
- name: Checkout target branch
if: ${{ steps.set-target-branch.outputs.TARGET_BRANCH != inputs.branch }}
uses: actions/checkout@v4
with:
ref: ${{ steps.set-target-branch.outputs.TARGET_BRANCH }}
path: checkout_branch
fetch-depth: 0

# Setup Python environment again after second checkout, as branches are different
- name: Setup Python environment again
if: ${{ steps.set-target-branch.outputs.TARGET_BRANCH != inputs.branch }}
uses: ./checkout_branch/.github/actions/python-setup
with:
pyproject_directory: checkout_branch/testsuite

# Determine image tag using the target branch
- name: Determine image tag
id: determine-test-image-tag
run: |
variants=(${{ inputs.variants }}) # split the variants string into an array
variants_args=()
for variant in "${variants[@]}"; do
variants_args+=("--variant" "$variant")
done
./testrun find_latest_image.py "${variants_args[@]}"
shell: bash
working-directory: checkout_branch/testsuite
59 changes: 55 additions & 4 deletions .github/workflows/docker-build-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -288,11 +288,61 @@ jobs:
# by this GHA. If there is a Forge namespace collision, Forge will pre-empt the existing test running in the namespace.
FORGE_NAMESPACE: forge-e2e-${{ needs.determine-docker-build-metadata.outputs.targetCacheId }}
SKIP_JOB: ${{ needs.file_change_determinator.outputs.only_docs_changed == 'true' }}

# This job determines the last released docker image tag, which is used by forge compat test.
fetch-last-released-docker-image-tag:
needs:
- permission-check
# runs only when need to run forge-compat-test or forge-framework-upgrade-test
if: |
!failure() && !cancelled() && needs.permission-check.result == 'success' && (
(github.event_name == 'push' && github.ref_name != 'main') ||
github.event_name == 'workflow_dispatch' ||
contains(github.event.pull_request.labels.*.name, 'CICD:run-e2e-tests') ||
contains(github.event.pull_request.labels.*.name, 'CICD:run-framework-upgrade-test') ||
github.event.pull_request.auto_merge != null ||
contains(github.event.pull_request.body, '#e2e')
)
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
ref: ${{ github.ref }}

# actions/get-latest-docker-image-tag requires docker utilities and having authenticated to internal docker image registries
- uses: aptos-labs/aptos-core/.github/actions/docker-setup@main
id: docker-setup
with:
GCP_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }}
GCP_SERVICE_ACCOUNT_EMAIL: ${{ secrets.GCP_SERVICE_ACCOUNT_EMAIL }}
EXPORT_GCP_PROJECT_VARIABLES: "false"
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DOCKER_ARTIFACT_REPO: ${{ secrets.AWS_DOCKER_ARTIFACT_REPO }}
GIT_CREDENTIALS: ${{ secrets.GIT_CREDENTIALS }}

- name: Get Docker Image Tag
uses: ./.github/actions/determine-or-use-target-branch-and-get-last-released-image
id: get-docker-image-tag
with:
base-branch: ${{ github.base_ref }}
variants: "failpoints performance"

- name: Add Image Tag to Step Summary
run: |
echo "## Image Tag for compat tests" >> $GITHUB_STEP_SUMMARY
echo "IMAGE_TAG: ${{ steps.get-docker-image-tag.outputs.IMAGE_TAG }}" >> $GITHUB_STEP_SUMMARY
echo "TARGET_BRANCH: ${{ steps.get-docker-image-tag.outputs.TARGET_BRANCH }}" >> $GITHUB_STEP_SUMMARY
outputs:
IMAGE_TAG: ${{ steps.get-docker-image-tag.outputs.IMAGE_TAG }}

# Run e2e compat test against testnet branch. This is a PR required job.
forge-compat-test:
needs:
needs:
- permission-check
- fetch-last-released-docker-image-tag
- determine-docker-build-metadata
- rust-images
- rust-images-failpoints
Expand All @@ -312,16 +362,17 @@ jobs:
with:
GIT_SHA: ${{ needs.determine-docker-build-metadata.outputs.gitSha }}
FORGE_TEST_SUITE: compat
IMAGE_TAG: 25a081116546670e62ca927ba90478de78557056 #aptos-node-v1.20
IMAGE_TAG: ${{ needs.fetch-last-released-docker-image-tag.outputs.IMAGE_TAG }}
FORGE_RUNNER_DURATION_SECS: 300
COMMENT_HEADER: forge-compat
FORGE_NAMESPACE: forge-compat-${{ needs.determine-docker-build-metadata.outputs.targetCacheId }}
SKIP_JOB: ${{ needs.file_change_determinator.outputs.only_docs_changed == 'true' }}

# Run forge framework upgradability test. This is a PR required job.
forge-framework-upgrade-test:
needs:
- permission-check
- fetch-last-released-docker-image-tag
- determine-docker-build-metadata
- rust-images
- rust-images-failpoints
Expand All @@ -340,7 +391,7 @@ jobs:
with:
GIT_SHA: ${{ needs.determine-docker-build-metadata.outputs.gitSha }}
FORGE_TEST_SUITE: framework_upgrade
IMAGE_TAG: 25a081116546670e62ca927ba90478de78557056 #aptos-node-v1.20
IMAGE_TAG: ${{ needs.fetch-last-released-docker-image-tag.outputs.IMAGE_TAG }}
FORGE_RUNNER_DURATION_SECS: 3600
COMMENT_HEADER: forge-framework-upgrade
FORGE_NAMESPACE: forge-framework-upgrade-${{ needs.determine-docker-build-metadata.outputs.targetCacheId }}
Expand Down
13 changes: 11 additions & 2 deletions .github/workflows/forge-stable.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ jobs:
runs-on: ubuntu-latest
outputs:
IMAGE_TAG: ${{ steps.get-docker-image-tag.outputs.IMAGE_TAG }}
IMAGE_TAG_FOR_COMPAT_TEST: ${{ steps.get-last-released-image-tag-for-compat-test.outputs.IMAGE_TAG }}
BRANCH: ${{ steps.determine-test-branch.outputs.BRANCH }}
BRANCH_HASH: ${{ steps.hash-branch.outputs.BRANCH_HASH }}
steps:
Expand Down Expand Up @@ -110,9 +111,17 @@ jobs:
branch: ${{ steps.determine-test-branch.outputs.BRANCH }}
variants: "failpoints performance"

- uses: ./.github/actions/determine-or-use-target-branch-and-get-last-released-image
id: get-last-released-image-tag-for-compat-test
with:
base-branch: ${{ steps.determine-test-branch.outputs.BRANCH }}
variants: "failpoints performance"

- name: Write summary
run: |
IMAGE_TAG=${{ steps.get-docker-image-tag.outputs.IMAGE_TAG }}
IMAGE_TAG_FOR_COMPAT_TEST=${{ steps.get-last-released-image-tag-for-compat-test.outputs.IMAGE_TAG }}
TARGET_BRANCH_TO_FETCH_IMAGE_FOR_COMPAT_TEST=${{ steps.get-last-released-image-tag-for-compat-test.outputs.TARGET_BRANCH }}
BRANCH=${{ steps.determine-test-branch.outputs.BRANCH }}
if [ -n "${BRANCH}" ]; then
echo "BRANCH: [${BRANCH}](https://github.com/${{ github.repository }}/tree/${BRANCH})" >> $GITHUB_STEP_SUMMARY
Expand All @@ -128,7 +137,7 @@ jobs:
uses: aptos-labs/aptos-core/.github/workflows/workflow-run-forge.yaml@main
secrets: inherit
with:
IMAGE_TAG: 25a081116546670e62ca927ba90478de78557056 #aptos-node-v1.20
IMAGE_TAG: ${{ needs.determine-test-metadata.outputs.IMAGE_TAG_FOR_COMPAT_TEST }}
FORGE_NAMESPACE: forge-framework-upgrade-${{ needs.determine-test-metadata.outputs.BRANCH_HASH }}
FORGE_RUNNER_DURATION_SECS: 7200 # Run for 2 hours
FORGE_TEST_SUITE: framework_upgrade
Expand Down Expand Up @@ -269,7 +278,7 @@ jobs:
FORGE_RUNNER_DURATION_SECS: 300 # Run for 5 minutes
# This will upgrade from testnet branch to the latest main
FORGE_TEST_SUITE: compat
IMAGE_TAG: 25a081116546670e62ca927ba90478de78557056 #aptos-node-v1.20
IMAGE_TAG: ${{ needs.determine-test-metadata.outputs.IMAGE_TAG_FOR_COMPAT_TEST }}
GIT_SHA: ${{ needs.determine-test-metadata.outputs.IMAGE_TAG }} # this is the git ref to checkout
POST_TO_SLACK: true

Expand Down
107 changes: 107 additions & 0 deletions testsuite/determine_target_branch_to_fetch_last_released_image.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import sys
import re

from test_framework.logging import init_logging, log
from test_framework.git import Git
from test_framework.shell import LocalShell

# GitHub output logic from determinator
from determinator import GithubOutput, write_github_output

# Initialize logging and the shell/git instances
shell = LocalShell()
git = Git(shell)

GH_OUTPUT_KEY = "TARGET_BRANCH"


def get_all_release_branches():
"""Get all aptos-release-vX.Y branches"""
pattern = "aptos-release-v*"
regex = r"refs/heads/(aptos-release-v\d+\.\d+)$"
branches = git.get_remote_branches_matching_pattern("origin", pattern, regex)
return sorted(branches, key=lambda x: [int(n) for n in x.split("v")[1].split(".")])


def get_all_release_branches_with_times():
"""Get all aptos-release-vX.Y branches with their creation times"""
branches = get_all_release_branches()
return [(branch, git.get_branch_creation_time(branch)) for branch in branches]


def get_latest_branch_for_previous_major(major):
"""Get the latest aptos-release-v(previous_major).Y branch"""
prev_major = int(major) - 1
pattern = f"aptos-release-v{prev_major}.*"
regex = rf"refs/heads/(aptos-release-v{prev_major}\.\d+)$"

branches = git.get_remote_branches_matching_pattern("origin", pattern, regex)

if branches:
return max(branches, key=lambda x: int(x.split(".")[-1]))
return None


def determine_target_branch(base_branch):
"""Determine the appropriate target branch based on the base branch"""
all_release_branches = get_all_release_branches_with_times()
if not all_release_branches:
raise ValueError("No release branches found")

if base_branch == "main":
# Sort by version numbers for 'main' branch
sorted_branches = sorted(
all_release_branches,
key=lambda x: [int(n) for n in x[0].split("v")[1].split(".")],
reverse=True,
)
return sorted_branches[0][0]

all_release_branches.sort(
key=lambda x: x[1], reverse=True
) # Sort by creation time, newest first

# If the base branch is a release branch, find the previous release branch
match = re.match(r"^aptos-release-v(\d+)\.(\d+)", base_branch)
if match:
major, minor = match.groups()
if int(minor) == 0:
return get_latest_branch_for_previous_major(major)
else:
return f"aptos-release-v{major}.{int(minor) - 1}"

# For other personal branches, find the latest release branch earlier than the current branch
base_branch_time = git.get_branch_creation_time(base_branch)
for branch, time in all_release_branches:
if time < base_branch_time:
return branch

# If no suitable branch found, return the earliest release branch
return all_release_branches[-1][0]


def main() -> None:
if len(sys.argv) != 2:
log.error("Usage: python determine_target_branch.py <base_branch>")
sys.exit(1)

base_branch = sys.argv[1]
try:
# Determine the target branch
target_branch = determine_target_branch(base_branch)
if target_branch is not None:
# Write the target branch to GitHub output
write_github_output(GithubOutput(GH_OUTPUT_KEY, str(target_branch)))
log.info(
f"Successfully wrote target branch to GitHub output: {target_branch}"
)
except Exception as e:
log.error(
f"Error determining target branch and writing to GitHub output: {e}\n"
"This may be an indication that you're running locally or the environment is not configured correctly."
)
sys.exit(1)


if __name__ == "__main__":
main()
Loading

0 comments on commit a033436

Please sign in to comment.