image: docker:latest stages: - test - build - push test: stage: test image: python:3.11-alpine script: - pip install -q -r requirements.txt - python -m unittest discover tests only: - main before_script: - apk add --no-cache docker-cli curl jq - | until docker info; do echo "Waiting for Docker to be ready..." sleep 5 done build: needs: - test stage: build script: - docker info - docker build -t $CI_REGISTRY/$CI_PROJECT_PATH:$CI_COMMIT_REF_SLUG . - docker tag $CI_REGISTRY/$CI_PROJECT_PATH:$CI_COMMIT_REF_SLUG $CI_REGISTRY/$CI_PROJECT_PATH:$CI_COMMIT_SHORT_SHA - docker tag $CI_REGISTRY/$CI_PROJECT_PATH:$CI_COMMIT_REF_SLUG $CI_REGISTRY/$CI_PROJECT_PATH:latest push: needs: - build stage: push script: - | CURRENT_IMAGE_HASH=$(docker inspect --format='{{index .RepoDigests 0}}' $CI_REGISTRY/$CI_PROJECT_PATH:$CI_COMMIT_REF_SLUG) EXISTING_IMAGE_HASH=$(curl -s --header "PRIVATE-TOKEN: $CI_JOB_TOKEN" "https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/registry/repositories/1/tags/$CI_COMMIT_REF_SLUG" | jq -r '.digest') if [ "$CURRENT_IMAGE_HASH" != "$EXISTING_IMAGE_HASH" ]; then echo "Image has changed, pushing to the registry..." echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY docker push $CI_REGISTRY/$CI_PROJECT_PATH:$CI_COMMIT_REF_SLUG docker push $CI_REGISTRY/$CI_PROJECT_PATH:$CI_COMMIT_SHORT_SHA docker push $CI_REGISTRY/$CI_PROJECT_PATH:latest else echo "Image is unchanged, skipping push." fi only: - main