# .gitlab-ci.yml.example # GitLab CI/CD pipeline: build, sign and push container image with Cosign # # Required CI/CD variables (Settings → CI/CD → Variables): # COSIGN_PRIVATE_KEY — contents of cosign.key (type: Variable, masked, protected) # COSIGN_PASSWORD — password for the private key (type: Variable, masked, protected) # REGISTRY_USER — registry login username (type: Variable) # REGISTRY_PASSWORD — registry login password (type: Variable, masked, protected) stages: - build - sign - verify variables: REGISTRY: git.realmanual.ru IMAGE: ${REGISTRY}/${CI_PROJECT_PATH} build: stage: build image: docker:27 services: - docker:27-dind variables: DOCKER_TLS_CERTDIR: "/certs" before_script: - echo "${REGISTRY_PASSWORD}" | docker login ${REGISTRY} -u ${REGISTRY_USER} --password-stdin - export VERSION=$(cat image/VERSION) script: - docker build -t ${IMAGE}:${CI_COMMIT_SHA} -t ${IMAGE}:${VERSION} image/ - docker push ${IMAGE}:${CI_COMMIT_SHA} - docker push ${IMAGE}:${VERSION} # save digest for sign/verify stages - docker inspect --format='{{index .RepoDigests 0}}' ${IMAGE}:${CI_COMMIT_SHA} | cut -d@ -f2 > digest.txt artifacts: paths: - digest.txt rules: - if: $CI_COMMIT_BRANCH == "main" sign: stage: sign image: alpine:3.20 before_script: - apk add --no-cache cosign script: - export IMAGE_DIGEST=$(cat digest.txt) - cosign sign --yes --key env://COSIGN_PRIVATE_KEY ${IMAGE}@${IMAGE_DIGEST} rules: - if: $CI_COMMIT_BRANCH == "main" verify: stage: verify image: alpine:3.20 before_script: - apk add --no-cache cosign script: - export IMAGE_DIGEST=$(cat digest.txt) - cosign verify --key keys/cosign.pub ${IMAGE}@${IMAGE_DIGEST} rules: - if: $CI_COMMIT_BRANCH == "main"