Use a manual job to trigger a selective build/push

This commit is contained in:
Kamil Trzciński 2021-02-02 13:30:18 +01:00
parent a9204d345d
commit 3acad93b15
4 changed files with 34 additions and 61 deletions

View file

@ -17,43 +17,51 @@ stages:
variables: variables:
DOCKER_DRIVER: overlay2 DOCKER_DRIVER: overlay2
DOCKER_HOST: tcp://docker:2375 DOCKER_HOST: tcp://docker:2375
FORCE_BUILD: "false"
# Run test job always
.test:
stage: test
rules:
- when: always
# Run build job only on a default branch when triggered manually
.build:
stage: build
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: manual
.test_build: &test_build .test_build: &test_build
stage: test extends: .test
script: script:
# Hack to set an array in /bin/sh # Hack to set an array in /bin/sh
# http://unix.stackexchange.com/a/137571 # http://unix.stackexchange.com/a/137571
- set -- $CI_JOB_NAME - set -- $CI_JOB_NAME
- docker build -f "Dockerfile.$1" . - docker pull "$CI_REGISTRY_IMAGE:$1" || true
except: - docker build --from-cache="$CI_REGISTRY_IMAGE:$1" -f "Dockerfile.$1" .
- master
.build_and_deploy: &build_and_deploy .build_and_deploy: &build_and_deploy
stage: build extends: .build
script: script:
- docker build --label "ci_pipeline_url=$CI_PIPELINE_URL" --label "ci_job_url=$CI_JOB_URL" -t "$CI_REGISTRY_IMAGE:$CI_JOB_NAME" -f "Dockerfile.$CI_JOB_NAME" . - docker pull "$CI_REGISTRY_IMAGE:$1" || true
- docker build --from-cache="$CI_REGISTRY_IMAGE:$1" --label "ci_pipeline_url=$CI_PIPELINE_URL" --label "ci_job_url=$CI_JOB_URL" -t "$CI_REGISTRY_IMAGE:$CI_JOB_NAME" -f "Dockerfile.$CI_JOB_NAME" .
- docker push "$CI_REGISTRY_IMAGE:$CI_JOB_NAME" - docker push "$CI_REGISTRY_IMAGE:$CI_JOB_NAME"
only:
- master
.test_custom: &test_custom .test_custom: &test_custom
stage: test extends: .test
script: script:
# Hack to set an array in /bin/sh # Hack to set an array in /bin/sh
# http://unix.stackexchange.com/a/137571 # http://unix.stackexchange.com/a/137571
- set -- $CI_JOB_NAME - set -- $CI_JOB_NAME
- ./scripts/custom-docker-build $1 - ./scripts/custom-docker-build $1
except: rules:
- master - when: always
.build_and_deploy_custom: &build_and_deploy_custom .build_and_deploy_custom: &build_and_deploy_custom
stage: build extends: .build
script: script:
- ./scripts/custom-docker-build $CI_JOB_NAME --label "ci_pipeline_url=$CI_PIPELINE_URL" --label "ci_job_url=$CI_JOB_URL" -t "$CI_REGISTRY_IMAGE:$CI_JOB_NAME" - ./scripts/custom-docker-build $CI_JOB_NAME --label "ci_pipeline_url=$CI_PIPELINE_URL" --label "ci_job_url=$CI_JOB_URL" -t "$CI_REGISTRY_IMAGE:$CI_JOB_NAME"
- push_if_needed "$CI_REGISTRY_IMAGE:$CI_JOB_NAME" - docker push "$CI_REGISTRY_IMAGE:$CI_JOB_NAME"
only:
- master
# Tests # Tests

View file

@ -66,17 +66,13 @@ the name would be `ruby-2.4-golang-1.9-git-2.14`.
1. Add a test task: `ruby-2.4-golang-1.9-git-2.14 test: *test_custom` 1. Add a test task: `ruby-2.4-golang-1.9-git-2.14 test: *test_custom`
1. Add a new build task: `ruby-2.4-golang-1.9-git-2.14: *build_and_deploy_custom` 1. Add a new build task: `ruby-2.4-golang-1.9-git-2.14: *build_and_deploy_custom`
#### Forcing custom images to be rebuilt #### Pushing a rebuild image
By default, once a custom image is built, tagged and pushed to the registry, it's To build (or rebuild) a given image and push it, you need to enable manual action for a given
not rebuilt to ensure an upstream dependency doesn't end up breaking our images job after it is merged to master.
unexpectedly.
For reference, this happened in the past: https://gitlab.com/gitlab-org/gitlab/issues/205192 By default we don't do it to ensure that an upstream dependency doesn't end up breaking our images
unexpectedly. For reference, this happened in the past: https://gitlab.com/gitlab-org/gitlab/issues/205192
In the rare case where the `Dockerfile.custom` file is updated and all custom
images shoulld be rebuild, you can start a new pipeline and set the variable
`FORCE_BUILD` to `true`.
## Note regarding Google Chrome ## Note regarding Google Chrome

View file

@ -1,25 +0,0 @@
function image_already_exists() {
image=$1
$(docker pull $image > /dev/null)
}
function build_if_needed() {
image=$1
if ! image_already_exists $image; then
docker build -t "$image" -f "Dockerfile.$image" .
else
echo "$image already exists, skipping build."
fi
}
function push_if_needed() {
image=$1
if ! image_already_exists $image; then
docker push "$image"
else
echo "$image already exists, skipping push."
fi
}

View file

@ -303,17 +303,11 @@ function build_custom_if_needed() {
build_image_name=$1 build_image_name=$1
full_image_name="$CI_REGISTRY_IMAGE:$build_image_name" full_image_name="$CI_REGISTRY_IMAGE:$build_image_name"
if [[ "$FORCE_BUILD" == "true" ]] || ! image_already_exists $full_image_name; then # This re-uses and builds an existing image if needed
docker_command=$(generate_command $@) docker pull "$full_image" || true
if [[ "$FORCE_BUILD" == "true" ]]; then docker_command=$(generate_command --from-cache="$full_image_name" $@)
echo "Force building $build_image_name due to \$FORCE_BUILD=true with $docker_command" echo "Building $build_image_name with $docker_command"
else eval $docker_command
echo "Building $build_image_name with $docker_command"
fi
eval $docker_command
else
echo "$build_image_name already exists, skipping build."
fi
} }
build_custom_if_needed $@ build_custom_if_needed $@