Using GitLab, I’m simulating the following behavior in my QA env:
- Commits (or merges into) to main, triggering build job to build the Docker image
- Merges main into stable (prod)
- Creates (manually) a tag from stable, triggering a job that retags the built image with the new tag and pushes it to AWS ECR
With my current .gitlab-ci.yml
, upon commit on main
, a pipeline is created containing only the build_qa
job. Upon tag creation after merge on stable, a new pipeline is created for the push_to_qa
job.
The problem is: the new pipeline can’t find the artifact when I try to docker load
, even though I’m using dependencies
.
This is the .gitlab-ci.yml
so far:
variables:
DOCKER_REGISTRY_QA: foo
DOCKER_REGISTRY_PROD: bar
AWS_DEFAULT_REGION: us-east-1
APP_NAME: test-pipeline-tags
DOCKER_HOST: tcp://docker:2375
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
IMAGE_VERSION_QA: latest
IMAGE_VERSION_PROD: latest
IMAGE_TAG_QA: "$DOCKER_REGISTRY_QA/$APP_NAME:$IMAGE_VERSION_QA"
IMAGE_TAG_PROD: "$DOCKER_REGISTRY_PROD/$APP_NAME:$IMAGE_VERSION_PROD"
IMAGE_FILE_NAME: qa_latest.tar
IMAGE_DIR: image
IMAGE_PATH: "$CI_PROJECT_DIR/$IMAGE_DIR/$IMAGE_FILE_NAME"
stages:
- build_qa
- push_qa
workflow:
rules:
- if: $CI_COMMIT_BRANCH == "main"
- if: $CI_MERGE_REQUEST_ID && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main"
- if: $CI_COMMIT_TAG =~ /^v(0|[1-9][0-9]*).(0|[1-9][0-9]*).(0|[1-9][0-9]*)$/
build_qa:
stage: build_qa
image:
name: amazon/aws-cli
entrypoint: [""]
rules:
- if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main"
- if: $CI_COMMIT_BRANCH == "main"
services:
- docker:dind
before_script:
- amazon-linux-extras install docker
- aws --version
- docker --version
- export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID_QA
- export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY_QA
- aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin $DOCKER_REGISTRY_QA
script:
- docker build -t $IMAGE_TAG_QA .
# tars the image and exports it to the artifact folder:
- mkdir $IMAGE_DIR
- docker save $IMAGE_TAG_QA > $IMAGE_PATH
artifacts:
expire_in: 2 hour
paths:
- $IMAGE_PATH
push_to_qa:
dependencies:
- build_qa
stage: push_qa
image:
name: amazon/aws-cli
entrypoint: [""]
rules:
- if: '$CI_COMMIT_TAG =~ /^v(0|[1-9][0-9]*).(0|[1-9][0-9]*).(0|[1-9][0-9]*)$/'
services:
- docker:dind
before_script:
- amazon-linux-extras install docker
- aws --version
- docker --version
- export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID_QA
- export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY_QA
- aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin $DOCKER_REGISTRY_QA
script:
# loads image from artifact
- docker load -i $IMAGE_PATH
# creates a new image tag based on the created tag:
- export NEW_IMAGE_TAG_QA="$DOCKER_REGISTRY_QA/$APP_NAME:$CI_COMMIT_TAG"
# retags the image to the created tag:
- docker tag $IMAGE_TAG_QA $NEW_IMAGE_TAG_QA
- docker push $NEW_IMAGE_TAG_QA
This is the full message:
$ docker load -i $IMAGE_PATH
open /builds/path/to/proj/test-pipeline-tags/image/qa_latest.tar: no such file or directory
Cleaning up project directory and file based variables
ERROR: Job failed: command terminated with exit code 1
I was trying without the $CI_PROJECT_DIR
before, and I thought that using it would be the fix but no success. The artifacts do exist and they haven’t expired.