Reputation: 2135
I have a project in GitLab that has pipeline jobs to build the image, run unit tests and push the built image to a repository.
What needs to happen:
Pipeline:
stages:
- build
- test
- release
...
build-image:
stage: build
extends:
- .kaniko-build
variables:
DOCKERFILE: Dockerfile
KUBERNETES_MEMORY_REQUEST: 2Gi
KUBERNETES_MEMORY_LIMIT: 2Gi
run-unit-tests:
stage: test
extends:
- .kaniko-build
variables:
DOCKERFILE: Unit-Tests.Dockerfile
KUBERNETES_MEMORY_REQUEST: 1Gi
KUBERNETES_MEMORY_LIMIT: 1Gi
after_script:
- mkdir -p test/surefire-reports
- cp -r /app-build/target/surefire-reports ./test
artifacts:
when: always
paths:
- test/surefire-reports
reports:
junit:
- test/surefire-reports/*.xml
push-to-harbor:
stage: release
extends:
- .release-local-image
variables:
SOURCE_IMAGE_NAME: $IMAGE_NAME
SOURCE_IMAGE_TAG: $CI_PIPELINE_ID
TARGET_PROJECT: phactory-images
TARGET_IMAGE_NAME: $IMAGE_NAME
TARGET_IMAGE_TAG: $CI_COMMIT_REF_SLUG
needs:
- build-image
...
What happens:
needs
clause of the push to harbor job allows it to run in parallel with the unit test job even though it's in a later stage.The problem with this is that if the unit test job fails due to a test failure, it does not prevent the built image from being pushed to the repository. This is not what I need.
A suggestion (see prior answer) was made to remove the needs
clause from the push to harbor job. This forces the push job to run after the unit test job. If the unit test job fails, the push job does not run. According to the documentation, GitLab by default, flows artifacts from prior jobs to following jobs.
Problem solved, right? Unfortunately, no. If the unit tests pass, the push job executes, but the image that's pushed is what results from running the unit test job Dockerfile. The build job artifacts are nowhere to be found.
I spent some time looking at other attributes of GitLab pipeline jobs and found the dependencies
clause (see link below). I've tried this in various ways, but it doesn't seem to do as advertised. It's still pushing the unit test Dockerfile image to the repository and completely ignoring the artifacts of the build job I specified.
push-to-harbor:
stage: release
extends:
- .release-local-image
variables:
SOURCE_IMAGE_NAME: $IMAGE_NAME
SOURCE_IMAGE_TAG: $CI_PIPELINE_ID
TARGET_PROJECT: phactory-images
TARGET_IMAGE_NAME: $IMAGE_NAME
TARGET_IMAGE_TAG: $CI_COMMIT_REF_SLUG
dependencies:
- build-image
Does the dependencies
clause not work? Am I using it the wrong way?
GitLab documentation:
https://docs.gitlab.com/ee/ci/yaml/#needs
Use needs to execute jobs out-of-order. Relationships between jobs that use needs can be visualized as a directed acyclic graph.
You can ignore stage ordering and run some jobs without waiting for others to complete. Jobs in multiple stages can run concurrently.
https://docs.gitlab.com/ee/ci/yaml/#dependencies
Use the dependencies keyword to define a list of jobs to fetch artifacts from. You can also set a job to download no artifacts at all.
If you do not use dependencies, all artifacts from previous stages are passed to each job.
Upvotes: 0
Views: 1006
Reputation: 1090
To archive your goal just remove needs
from push-to-harbor
stage. In this case each job will be dependent on previous jobs and will run only in case if all previous jobs finished successfully. This is default behavior. Also by default all artifacts from previous stages are passed to each job.
Upvotes: 1