From bf694cbee3574b3e67ac32ba38d9e0b91da8b9d7 Mon Sep 17 00:00:00 2001 From: nolan1999 Date: Sat, 4 Oct 2025 15:08:36 +0200 Subject: [PATCH 1/5] Refactor deployment + change AWS account --- .github/workflows/publish-version-ecr.yaml | 111 +++++++++++++++++ .github/workflows/publish-version-gh.yaml | 56 +++++++++ .github/workflows/publish-version.yaml | 137 --------------------- README.md | 2 +- application_config.yaml | 8 +- 5 files changed, 172 insertions(+), 142 deletions(-) create mode 100644 .github/workflows/publish-version-ecr.yaml create mode 100644 .github/workflows/publish-version-gh.yaml delete mode 100644 .github/workflows/publish-version.yaml diff --git a/.github/workflows/publish-version-ecr.yaml b/.github/workflows/publish-version-ecr.yaml new file mode 100644 index 0000000..7202892 --- /dev/null +++ b/.github/workflows/publish-version-ecr.yaml @@ -0,0 +1,111 @@ +name: Publish version to AWS ECR + +on: + workflow_dispatch: # manual trigger to publish prod/dev version + workflow_run: # trigger on GH version to publish prod version + workflows: ["Publish version to GitHub"] + types: + - completed + branches: + - main + +jobs: + build-and-push: + name: Build and push Docker image + runs-on: ubuntu-latest + + steps: + - name: Set version + id: set-version + run: | + if [ "${{ github.event_name }}" == "workflow_run" ]; then + POETRY_VERSION=$(grep -E '^requires-poetry = ' pyproject.toml | sed -E 's/requires-poetry = "(.*)"/\1/') + pip install poetry==$POETRY_VERSION + REF=refs/tags/$(poetry version -s) + PROD=true + VERSION=$REF + else + REF=$GITHUB_REF + if [[ "$GITHUB_REF" == refs/tags/* ]]; then + PROD=true + VERSION=${GITHUB_REF#refs/tags/} + else + PROD=false + VERSION=dev-${GITHUB_REF#refs/heads/}-${GITHUB_SHA::7} + fi + fi + echo "REF=$REF" >> $GITHUB_OUTPUT + echo "PROD=$PROD" >> $GITHUB_OUTPUT + echo "VERSION=$VERSION" >> $GITHUB_OUTPUT + + - name: Checkout code + uses: actions/checkout@v3 + with: + ref: ${{ steps.set-version.outputs.REF }} + fetch-depth: 0 + + - name: Get Python version + id: get-python-version + run: | + pip install toml + PYTHON_VERSION=$(python -c 'import scripts.vars; scripts.vars.get_python_version()') + echo "PYTHON_VERSION=$PYTHON_VERSION" >> $GITHUB_OUTPUT + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v2 + with: + aws-access-key-id: ${{ secrets.ECR_AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.ECR_AWS_SECRET_ACCESS_KEY }} + aws-region: us-east-1 # required for Public ECR + + - name: Login to AWS Public ECR + uses: aws-actions/amazon-ecr-login@v1 + with: + registry-type: public + + - name: Build and push Docker image + id: build-and-push + env: + VERSION: ${{ steps.set-version.outputs.VERSION }} + PROD: ${{ steps.set-version.outputs.PROD }} + ECR_REGISTRY: public.ecr.aws/w2b7b8c0 + ECR_REPOSITORY: decode-cloud/user-api + PYTHON_VERSION: ${{ steps.get-python-version.outputs.PYTHON_VERSION }} + run: | + IMAGE_REF=$ECR_REGISTRY/$ECR_REPOSITORY:$VERSION + echo "IMAGE_REF=$IMAGE_REF" >> $GITHUB_OUTPUT + if docker manifest inspect $IMAGE_REF > /dev/null 2>&1; then + NEW_IMAGE=false + echo "Image $IMAGE_REF already exists, nothing pushed" >> $GITHUB_STEP_SUMMARY + else + NEW_IMAGE=true + docker build --build-arg PYTHON_VERSION=$PYTHON_VERSION -t $IMAGE_REF . + docker push $IMAGE_REF + echo "## 🚀 Published Docker Image: $IMAGE_REF" >> $GITHUB_STEP_SUMMARY + if [[ $PROD == "true" ]]; then + SET_LATEST=true + LATEST_EXISTS=$(docker manifest inspect $ECR_REGISTRY/$ECR_REPOSITORY:latest > /dev/null 2>&1 && echo "true" || echo "false") + if [[ $LATEST_EXISTS == "true" ]]; then + LATEST_LABELS=$(docker manifest inspect $ECR_REGISTRY/$ECR_REPOSITORY:latest | grep -o '"org.opencontainers.image.version":"[^"]*"' | cut -d'"' -f4 || echo "") + if printf '%s\n%s\n' "$LATEST_LABELS" "$VERSION" | sort -V | head -n1 | grep -q "^$VERSION$"; then + SET_LATEST=false + fi + fi + if [[ $SET_LATEST == "true" ]]; then + docker tag $IMAGE_REF $ECR_REGISTRY/$ECR_REPOSITORY:latest + docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest + echo "Also tagged as: \`$ECR_REGISTRY/$ECR_REPOSITORY:latest\`" >> $GITHUB_STEP_SUMMARY + fi + fi + fi + echo "NEW_IMAGE=$NEW_IMAGE" >> $GITHUB_OUTPUT + + - name: Add to GH release + if: steps.build-and-push.outputs.NEW_IMAGE == 'true' && steps.set-version.outputs.PROD == 'true' + uses: tubone24/update_release@v1.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAG_NAME: ${{ steps.set-version.outputs.VERSION }} + with: + body: "**Published image (AWS ECR Public):** `{{ steps.build-and-push.outputs.IMAGE_REF }}`" + is_append_body: true diff --git a/.github/workflows/publish-version-gh.yaml b/.github/workflows/publish-version-gh.yaml new file mode 100644 index 0000000..3a3bc15 --- /dev/null +++ b/.github/workflows/publish-version-gh.yaml @@ -0,0 +1,56 @@ +name: Publish version to GitHub + +on: + push: + branches: + - main + +jobs: + create-version: + name: Create GH version and tag + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Set version + id: set-version + run: | + POETRY_VERSION=$(grep -E '^requires-poetry = ' pyproject.toml | sed -E 's/requires-poetry = "(.*)"/\1/') + pip install poetry==$POETRY_VERSION + VERSION=$(poetry version -s) + echo "VERSION=$VERSION" >> $GITHUB_OUTPUT + + - name: Check if release exists + id: check-release + env: + VERSION: ${{ steps.set-version.outputs.VERSION }} + run: | + git fetch --tags + if [ -n "$(git tag -l "$VERSION")" ]; then + echo "## ⚠️ Tag $VERSION already exists in git. Skipping publish." >> $GITHUB_STEP_SUMMARY + echo "skip_publish=true" >> $GITHUB_OUTPUT + else + echo "skip_publish=false" >> $GITHUB_OUTPUT + fi + + - name: Create and push annotated git tag + if: steps.check-release.outputs.skip_publish != 'true' + env: + VERSION: ${{ steps.set-version.outputs.VERSION }} + run: | + git config user.name "github-actions" + git config user.email "github-actions@github.com" + git tag -a "$VERSION" -m "Release $VERSION" + git push origin "$VERSION" + + - name: Create GitHub release + if: steps.check-release.outputs.skip_publish != 'true' + uses: softprops/action-gh-release@v1 + with: + tag_name: ${{ steps.set-version.outputs.VERSION }} + name: Release ${{ steps.set-version.outputs.VERSION }} + generate_release_notes: true diff --git a/.github/workflows/publish-version.yaml b/.github/workflows/publish-version.yaml deleted file mode 100644 index d153ba0..0000000 --- a/.github/workflows/publish-version.yaml +++ /dev/null @@ -1,137 +0,0 @@ -name: Publish version to GitHub and ECR - -on: - workflow_dispatch: - inputs: - version: - type: choice - description: 'Publish type (dev for test image, prod for release from pyproject.toml)' - required: true - options: - - dev - - prod - default: 'dev' - push: - branches: - - main - -jobs: - build-and-push: - name: Build and push Docker image - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - name: Set version type - id: set-version-type - run: | - if [ "${{ github.event_name }}" = "push" ]; then - VERSION_TYPE="prod" - else - VERSION_TYPE="${{ github.event.inputs.version }}" - fi - echo "VERSION_TYPE=$VERSION_TYPE" >> $GITHUB_OUTPUT - - - name: Validate branch for dev - if: ${{ steps.set-version-type.outputs.VERSION_TYPE == 'prod' && github.ref != 'refs/heads/main' }} - run: | - echo "Error: Only 'dev' builds are allowed on non-main branches." - exit 1 - - - name: Set version - id: set-version - run: | - if [ "${{ steps.set-version-type.outputs.VERSION_TYPE }}" = "prod" ]; then - POETRY_VERSION=$(grep -E '^requires-poetry = ' pyproject.toml | sed -E 's/requires-poetry = "(.*)"/\1/') - pip install poetry==$POETRY_VERSION - VERSION=$(poetry version -s) - else - VERSION="dev-${GITHUB_SHA::7}" - fi - echo "VERSION=$VERSION" - echo "VERSION=$VERSION" >> $GITHUB_OUTPUT - - - name: Check if release exists (prod) - if: ${{ steps.set-version-type.outputs.VERSION_TYPE == 'prod' }} - id: check-release - env: - VERSION: ${{ steps.set-version.outputs.VERSION }} - run: | - git fetch --tags - if [ -n "$(git tag -l "$VERSION")" ]; then - echo "## ⚠️ Tag $VERSION already exists in git. Skipping publish." >> $GITHUB_STEP_SUMMARY - echo "skip_publish=true" >> $GITHUB_OUTPUT - else - echo "skip_publish=false" >> $GITHUB_OUTPUT - fi - - - name: Get Python version - if: steps.check-release.outputs.skip_publish != 'true' - id: get-python-version - run: | - pip install toml - PYTHON_VERSION=$(python -c 'import scripts.vars; scripts.vars.get_python_version()') - echo "Python version: $PYTHON_VERSION" - echo "PYTHON_VERSION=$PYTHON_VERSION" >> $GITHUB_OUTPUT - - - name: Configure AWS credentials - if: steps.check-release.outputs.skip_publish != 'true' - uses: aws-actions/configure-aws-credentials@v2 - with: - aws-access-key-id: ${{ secrets.ECR_AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.ECR_AWS_SECRET_ACCESS_KEY }} - aws-region: us-east-1 # required for Public ECR - - - name: Login to AWS Public ECR - if: steps.check-release.outputs.skip_publish != 'true' - id: login-ecr - uses: aws-actions/amazon-ecr-login@v1 - with: - registry-type: public - - - name: Build and push Docker image - if: steps.check-release.outputs.skip_publish != 'true' - env: - VERSION: ${{ steps.set-version.outputs.VERSION }} - ECR_REGISTRY: public.ecr.aws/g0e9g3b1 - ECR_REPOSITORY: decode-cloud/user-api - PYTHON_VERSION: ${{ steps.get-python-version.outputs.PYTHON_VERSION }} - run: | - echo "Building image: $ECR_REGISTRY/$ECR_REPOSITORY:$VERSION" - docker build --build-arg PYTHON_VERSION=$PYTHON_VERSION -t $ECR_REGISTRY/$ECR_REPOSITORY:$VERSION . - docker push $ECR_REGISTRY/$ECR_REPOSITORY:$VERSION - - if [[ "$VERSION" != dev-* ]]; then - echo "Tagging as latest" - docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$VERSION $ECR_REGISTRY/$ECR_REPOSITORY:latest - docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest - fi - - echo "## 🚀 Docker Image Published" >> $GITHUB_STEP_SUMMARY - echo "\`$ECR_REGISTRY/$ECR_REPOSITORY:$VERSION\`" >> $GITHUB_STEP_SUMMARY - if [[ "$VERSION" != dev-* ]]; then - echo "" >> $GITHUB_STEP_SUMMARY - echo "Also tagged as: \`$ECR_REGISTRY/$ECR_REPOSITORY:latest\`" >> $GITHUB_STEP_SUMMARY - fi - - - name: Create and push annotated git tag - if: steps.check-release.outputs.skip_publish != 'true' && steps.set-version-type.outputs.VERSION_TYPE == 'prod' - env: - VERSION: ${{ steps.set-version.outputs.VERSION }} - run: | - git config user.name "github-actions" - git config user.email "github-actions@github.com" - git tag -a "$VERSION" -m "Release $VERSION" - git push origin "$VERSION" - - - name: Create GitHub release - if: steps.check-release.outputs.skip_publish != 'true' && steps.set-version-type.outputs.VERSION_TYPE == 'prod' - uses: softprops/action-gh-release@v1 - with: - tag_name: ${{ steps.set-version.outputs.VERSION }} - name: Release ${{ steps.set-version.outputs.VERSION }} - generate_release_notes: true diff --git a/README.md b/README.md index c722534..ff1f4bb 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,7 @@ decode: - "--log_path=/files/log" env: [] handler: - image_url: "public.ecr.aws/g0e9g3b1/decode:v0_10_1" + image_url: "public.ecr.aws/w2b7b8c0/decode:v0_10_1" files_down: config_id: config data_ids: data diff --git a/application_config.yaml b/application_config.yaml index f1235d5..c496bca 100644 --- a/application_config.yaml +++ b/application_config.yaml @@ -11,7 +11,7 @@ decode: - "--log_path=/files/log" env: [] handler: - image_url: "public.ecr.aws/g0e9g3b1/decode:v0_10_1" + image_url: "public.ecr.aws/w2b7b8c0/decode:v0_10_1" files_down: config_id: config data_ids: data @@ -37,7 +37,7 @@ decode: - "--emitter_path=/files/output/emitter.h5" env: [] handler: - image_url: "public.ecr.aws/g0e9g3b1/decode:v0_10_1" + image_url: "public.ecr.aws/w2b7b8c0/decode:v0_10_1" files_down: config_id: config data_ids: data @@ -66,7 +66,7 @@ decode: - "Paths.trafo=$(find /files/data -name '*_trafo.mat' | head -n 1 | grep . || echo null)" env: [] handler: - image_url: "public.ecr.aws/g0e9g3b1/decode:latest" + image_url: "public.ecr.aws/w2b7b8c0/decode:latest" files_down: config_id: config_tmp data_ids: data @@ -94,7 +94,7 @@ comet: - " > /files/log/log.log" env: [] handler: - image_url: "public.ecr.aws/g0e9g3b1/comet:latest" + image_url: "public.ecr.aws/w2b7b8c0/comet:latest" files_down: config_id: config data_ids: data From c21635137cff10b6f46199e0efed127944a54fa5 Mon Sep 17 00:00:00 2001 From: nolan1999 Date: Sat, 4 Oct 2025 17:13:53 +0200 Subject: [PATCH 2/5] Adapt integration tests to avoid S3 collisions --- tests/conftest.py | 45 +++++++++++++++++++++++++----- tests/integration/conftest.py | 24 ++++++++-------- tests/unit/core/test_filesystem.py | 6 ++-- 3 files changed, 53 insertions(+), 22 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 9e62ac2..847557d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,3 +1,4 @@ +import datetime import secrets import time from typing import Any, Generator @@ -13,6 +14,9 @@ from api.dependencies import enqueueing_function_dep from api.main import app +TEST_BUCKET_PREFIX = "decode-cloud-user-api-tests-" +REGION_NAME: BucketLocationConstraintType = "eu-central-1" + @pytest.fixture(scope="module") def monkeypatch_module() -> Generator[pytest.MonkeyPatch, Any, None]: @@ -34,8 +38,8 @@ def enqueueing_func(monkeypatch_module: pytest.MonkeyPatch) -> MagicMock: class RDSTestingInstance: def __init__(self, db_name: str): self.db_name = db_name - self.rds_client = boto3.client("rds", "eu-central-1") - self.ec2_client = boto3.client("ec2", "eu-central-1") + self.rds_client = boto3.client("rds", REGION_NAME) + self.ec2_client = boto3.client("ec2", REGION_NAME) self.add_ingress_rule() self.db_url = self.create_db_url() self.delete_db_tables() @@ -86,13 +90,13 @@ def delete_db_tables(self) -> None: def get_db_password(self) -> str: secret_name = "decode-cloud-tests-db-pwd" - sm_client = boto3.client("secretsmanager", "eu-central-1") + sm_client = boto3.client("secretsmanager", REGION_NAME) try: return sm_client.get_secret_value(SecretId=secret_name)["SecretString"] except botocore.exceptions.ClientError as e: if e.response["Error"]["Code"] == "ResourceNotFoundException": secret = secrets.token_urlsafe(32) - boto3.client("secretsmanager", "eu-central-1").create_secret( + boto3.client("secretsmanager", REGION_NAME).create_secret( Name=secret_name, SecretString=secret ) return secret @@ -141,9 +145,10 @@ def cleanup(self) -> None: class S3TestingBucket: - def __init__(self, bucket_name: str): - self.bucket_name = bucket_name - self.region_name: BucketLocationConstraintType = "eu-central-1" + def __init__(self, bucket_name_suffix: str): + # S3 bucket names must be globally unique - avoid collisions by adding suffix + self.bucket_name = f"{TEST_BUCKET_PREFIX}-{bucket_name_suffix}" + self.region_name: BucketLocationConstraintType = REGION_NAME self.s3_client = boto3.client( "s3", region_name=self.region_name, @@ -177,3 +182,29 @@ def initialize_bucket(self) -> None: CreateBucketConfiguration={"LocationConstraint": self.region_name}, ) self.s3_client.get_waiter("bucket_exists").wait(Bucket=self.bucket_name) + + +@pytest.fixture(scope="session") +def bucket_suffix() -> str: + return datetime.datetime.now(datetime.UTC).strftime("%Y%m%d%H%M%S") + + +@pytest.mark.aws +@pytest.fixture(scope="session", autouse=True) +def cleanup_old_test_buckets() -> None: + """ + Find and delete all S3 buckets with the test prefix. + This helps clean up buckets from previous test runs. + """ + s3_client = boto3.client("s3", region_name=REGION_NAME) + response = s3_client.list_buckets(Prefix=TEST_BUCKET_PREFIX) + for bucket in response["Buckets"]: + bucket_name = bucket["Name"] + s3 = boto3.resource("s3", region_name=REGION_NAME) + s3_bucket = s3.Bucket(bucket_name) + bucket_versioning = s3.BucketVersioning(bucket_name) + if bucket_versioning.status == "Enabled": + s3_bucket.object_versions.delete() + else: + s3_bucket.objects.all().delete() + s3_client.delete_bucket(Bucket=bucket_name) diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 83fd9e9..cce0ac1 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -28,7 +28,7 @@ ) from api.main import app from api.models import Job -from tests.conftest import RDSTestingInstance, S3TestingBucket +from tests.conftest import REGION_NAME, RDSTestingInstance, S3TestingBucket @pytest.fixture(scope="module") @@ -90,10 +90,11 @@ def db_session(env: str) -> Generator[Session, Any, None]: @pytest.fixture def base_filesystem( - env: str, base_user_dir: str, monkeypatch_module: pytest.MonkeyPatch + env: str, + base_user_dir: str, + monkeypatch_module: pytest.MonkeyPatch, + bucket_suffix: str, ) -> Generator[FileSystem, Any, None]: - bucket_name = "decode-cloud-user-integration-tests" - if env == "local": base_user_dir = f"./{base_user_dir}" @@ -102,15 +103,10 @@ def base_filesystem( "user_data_root_path", base_user_dir, ) - monkeypatch_module.setattr( - settings, - "s3_bucket", - bucket_name, - ) monkeypatch_module.setattr( settings, "s3_region", - "eu-central-1", + REGION_NAME, ) monkeypatch_module.setattr( settings, @@ -124,7 +120,13 @@ def base_filesystem( shutil.rmtree(base_user_dir, ignore_errors=True) elif env == "aws": - testing_bucket = S3TestingBucket(bucket_name) + testing_bucket = S3TestingBucket(bucket_suffix) + # Update settings to use the actual unique bucket name created by S3TestingBucket + monkeypatch_module.setattr( + settings, + "s3_bucket", + testing_bucket.bucket_name, + ) yield S3Filesystem( base_user_dir, testing_bucket.s3_client, testing_bucket.bucket_name ) diff --git a/tests/unit/core/test_filesystem.py b/tests/unit/core/test_filesystem.py index e75c2ca..2312624 100644 --- a/tests/unit/core/test_filesystem.py +++ b/tests/unit/core/test_filesystem.py @@ -255,8 +255,6 @@ def data_file1( class TestS3Filesystem(_TestFilesystem): - bucket_name = "decode-cloud-user-filesystem-tests" - @pytest.fixture( scope="class", params=[True, pytest.param(False, marks=pytest.mark.aws)] ) @@ -265,11 +263,11 @@ def mock_aws_(self, request: pytest.FixtureRequest) -> bool: @pytest.fixture(scope="class") def filesystem( - self, base_dir: str, mock_aws_: bool + self, base_dir: str, mock_aws_: bool, bucket_suffix: str ) -> Generator[S3Filesystem, Any, None]: context_manager = mock_aws if mock_aws_ else nullcontext with context_manager(): - testing_bucket = S3TestingBucket(self.bucket_name) + testing_bucket = S3TestingBucket(bucket_suffix) yield S3Filesystem( base_dir, testing_bucket.s3_client, testing_bucket.bucket_name ) From d5ad68d6925a195ad41088aff2c40ee892c3e929 Mon Sep 17 00:00:00 2001 From: nolan1999 Date: Sat, 4 Oct 2025 17:20:52 +0200 Subject: [PATCH 3/5] no need for weird checkout --- .github/workflows/publish-version-ecr.yaml | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/.github/workflows/publish-version-ecr.yaml b/.github/workflows/publish-version-ecr.yaml index 7202892..31d0640 100644 --- a/.github/workflows/publish-version-ecr.yaml +++ b/.github/workflows/publish-version-ecr.yaml @@ -15,17 +15,20 @@ jobs: runs-on: ubuntu-latest steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set version id: set-version run: | if [ "${{ github.event_name }}" == "workflow_run" ]; then POETRY_VERSION=$(grep -E '^requires-poetry = ' pyproject.toml | sed -E 's/requires-poetry = "(.*)"/\1/') pip install poetry==$POETRY_VERSION - REF=refs/tags/$(poetry version -s) PROD=true - VERSION=$REF + VERSION=$(poetry version -s) else - REF=$GITHUB_REF if [[ "$GITHUB_REF" == refs/tags/* ]]; then PROD=true VERSION=${GITHUB_REF#refs/tags/} @@ -34,16 +37,9 @@ jobs: VERSION=dev-${GITHUB_REF#refs/heads/}-${GITHUB_SHA::7} fi fi - echo "REF=$REF" >> $GITHUB_OUTPUT echo "PROD=$PROD" >> $GITHUB_OUTPUT echo "VERSION=$VERSION" >> $GITHUB_OUTPUT - - name: Checkout code - uses: actions/checkout@v3 - with: - ref: ${{ steps.set-version.outputs.REF }} - fetch-depth: 0 - - name: Get Python version id: get-python-version run: | From b66f8041fd8ebe96905ba4b11971d0de5bc9097d Mon Sep 17 00:00:00 2001 From: Arthur Jaques Date: Sat, 4 Oct 2025 17:40:51 +0200 Subject: [PATCH 4/5] Update .github/workflows/publish-version-ecr.yaml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/workflows/publish-version-ecr.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-version-ecr.yaml b/.github/workflows/publish-version-ecr.yaml index 31d0640..521319b 100644 --- a/.github/workflows/publish-version-ecr.yaml +++ b/.github/workflows/publish-version-ecr.yaml @@ -103,5 +103,5 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAG_NAME: ${{ steps.set-version.outputs.VERSION }} with: - body: "**Published image (AWS ECR Public):** `{{ steps.build-and-push.outputs.IMAGE_REF }}`" + body: "**Published image (AWS ECR Public):** `${{ steps.build-and-push.outputs.IMAGE_REF }}`" is_append_body: true From 2a5c870d17e96ab8b3af7520186fd54b795a4424 Mon Sep 17 00:00:00 2001 From: nolan1999 Date: Sat, 4 Oct 2025 17:48:05 +0200 Subject: [PATCH 5/5] correct ref --- .github/workflows/publish-version-ecr.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/publish-version-ecr.yaml b/.github/workflows/publish-version-ecr.yaml index 521319b..5bf99a2 100644 --- a/.github/workflows/publish-version-ecr.yaml +++ b/.github/workflows/publish-version-ecr.yaml @@ -28,7 +28,9 @@ jobs: pip install poetry==$POETRY_VERSION PROD=true VERSION=$(poetry version -s) + REF=refs/tags/$VERSION else + REF=$GITHUB_REF if [[ "$GITHUB_REF" == refs/tags/* ]]; then PROD=true VERSION=${GITHUB_REF#refs/tags/} @@ -39,6 +41,14 @@ jobs: fi echo "PROD=$PROD" >> $GITHUB_OUTPUT echo "VERSION=$VERSION" >> $GITHUB_OUTPUT + echo "REF=$REF" >> $GITHUB_OUTPUT + + # on main, we do not want necessarily the latest commit, but the one that was tagged + - name: Checkout code + uses: actions/checkout@v3 + with: + ref: ${{ steps.set-version.outputs.REF }} + fetch-depth: 0 - name: Get Python version id: get-python-version