Skip to content

Commit 898adad

Browse files
author
David Ferlay
authored
Merge pull request #264 from davidferlay/deployscript
Adding script for Continuous Delivery
2 parents 8ab89b3 + 1c7e50e commit 898adad

File tree

7 files changed

+299
-0
lines changed

7 files changed

+299
-0
lines changed

.gitlab-ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,8 @@ deploy:storybook:
246246
<<: *runner_tag_selection
247247
<<: *only_branches
248248
<<: *only_var_theme
249+
except:
250+
- tags
249251

250252
test:behat:
251253
stage: tests
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Example of .gitlab-ci.yml jobs
2+
3+
stages:
4+
- deliver
5+
6+
.delivery_template: &delivery_template
7+
stage: deliver
8+
dependencies:
9+
- prepare:front # Where front dependencies are installed and assets are builded
10+
- prepare:back # Where back dependencies are installed
11+
allow_failure: true
12+
retry:
13+
max: 2
14+
only:
15+
- tags
16+
except:
17+
- branches
18+
after_script:
19+
- docker rmi -f ${CI_PROJECT_NAME}-artifact:${CI_COMMIT_REF_NAME}
20+
- docker rmi -f ${DELIVERY_REPOSITORIES_DOCKER_REGISTRY_DOMAIN_1}/${CI_PROJECT_NAME}-artifact:${CI_COMMIT_REF_NAME}
21+
- docker images --quiet --filter=dangling=true | xargs --no-run-if-empty docker rmi -f
22+
- docker images
23+
24+
delivery:
25+
<<: *delivery_template
26+
<<: *runner_tag_selection
27+
script:
28+
- echo " - Start of CI job"
29+
- date; pwd; ls -lah;
30+
- echo ${CI_PROJECT_NAME}
31+
- echo ${CI_COMMIT_REF_NAME}
32+
- echo ${CI_PROJECT_URL}
33+
- echo ${DELIVERY_REPOSITORIES_DOCKER_REGISTRY_DOMAIN_1}
34+
- echo ${DELIVERY_REPOSITORIES_USERNAME}
35+
- docker info
36+
- docker build -t ${CI_PROJECT_NAME}-artifact:${CI_COMMIT_REF_NAME} -f scripts/delivery-docker/Dockerfile . --no-cache --force-rm --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` --build-arg BUILD_URL="${CI_PROJECT_URL}" --build-arg BUILD_DESC="Drupal build artifact" --build-arg BUILD_NAME="${CI_PROJECT_NAME}" --build-arg BUILD_MAINTAINER="${CI_PROJECT_NAME}/mgmt@skilld.cloud"
37+
- docker tag ${CI_PROJECT_NAME}-artifact:${CI_COMMIT_REF_NAME} ${DELIVERY_REPOSITORIES_DOCKER_REGISTRY_DOMAIN_1}/${CI_PROJECT_NAME}-artifact:${CI_COMMIT_REF_NAME}
38+
- docker tag ${CI_PROJECT_NAME}-artifact:${CI_COMMIT_REF_NAME} ${DELIVERY_REPOSITORIES_DOCKER_REGISTRY_DOMAIN_1}/${CI_PROJECT_NAME}-artifact:latest
39+
- docker inspect ${CI_PROJECT_NAME}-artifact:${CI_COMMIT_REF_NAME}
40+
- docker login ${DELIVERY_REPOSITORIES_DOCKER_REGISTRY_DOMAIN_1} --username ${DELIVERY_REPOSITORIES_USERNAME} --password ${DELIVERY_REPOSITORIES_PASSWORD}
41+
- docker push ${DELIVERY_REPOSITORIES_DOCKER_REGISTRY_DOMAIN_1}/${CI_PROJECT_NAME}-artifact:${CI_COMMIT_REF_NAME}
42+
- docker push ${DELIVERY_REPOSITORIES_DOCKER_REGISTRY_DOMAIN_1}/${CI_PROJECT_NAME}-artifact:latest
43+
- echo " - End of CI job"
44+
artifacts:
45+
name: "$CI_COMMIT_REF_NAME:$CI_COMMIT_SHA:delivery"
46+
expire_in: 1d
47+
paths:
48+
- ./*
49+
50+
Delivery 2: # Job can then be duplicated to deliver to multiples registries (just use a different REPOSITORIES_DOCKER_REGISTRY_DOMAIN_N variable for each)
51+
...
52+

scripts/delivery-docker/Dockerfile

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
FROM scratch
2+
3+
ARG BUILD_DATE
4+
ARG BUILD_NAME
5+
ARG BUILD_DESC
6+
ARG BUILD_URL
7+
ARG BUILD_MAINTAINER
8+
9+
LABEL org.label-schema.build-date=$BUILD_DATE \
10+
org.label-schema.name=$BUILD_NAME \
11+
org.label-schema.description=$BUILD_DESC \
12+
org.label-schema.vcs-url=$BUILD_URL \
13+
maintainer=$BUILD_MAINTAINER
14+
15+
WORKDIR src
16+
COPY . .
17+
18+

scripts/delivery-docker/README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Delivering script
2+
3+
## What
4+
5+
- This script deliver the current tag from a repo to a docker registry using a Gitlab CI job, as part of continuous deployments
6+
- You can also deliver to multiple registries at the same time using multiple jobs in the same pipeline
7+
8+
## Why
9+
10+
Why not use the built-in registry functionality Gitlab-ci and other repository services usualy offer ?
11+
12+
- Because it doesn't work when your git repo is protected behind a basic authentication
13+
- Because mirroring to multiple registries at once is sometime a premium (paid) feature
14+
- Because artifacts (downloaded and generated files) are usualy not versioned in git
15+
16+
## Setup
17+
18+
2 files are required :
19+
- `.gitlab-ci.yml`
20+
- `Dockerfile`
21+
22+
1. Define a delivery CI job like "Delivery 1" in .gitlab-ci.yml, as shown in .gitlab-ci.delivery_via_docker_example.yml
23+
- To include artefact dependencies, this CI job should be positioned after all dependencies have been built and installed and use the [dependencies](https://docs.gitlab.com/ee/ci/yaml/#dependencies) key word
24+
1. In Gitlab UI, add the following custom CI/CD variables :
25+
- DELIVERY_REPOSITORIES_DOCKER_REGISTRY_DOMAIN_1 : Docker repository to which deliver current tag (you can have multiple ones)
26+
- DELIVERY_REPOSITORIES_USERNAME : Service account credentials to use to push Docker image
27+
- DELIVERY_REPOSITORIES_PASSWORD : Service account credentials to use to push Docker image
28+
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Example of .gitlab-ci.yml jobs
2+
# Use with scripts/delivery/deliver_current_tag_via_git.sh
3+
4+
stages:
5+
- deliver
6+
7+
.delivery_via_git_template: &delivery_via_git_template
8+
stage: deliver
9+
dependencies:
10+
- prepare:front # Where front dependencies are installed and assets are builded
11+
- prepare:back # Where back dependencies are installed
12+
allow_failure: true
13+
retry:
14+
max: 2
15+
only:
16+
- tags
17+
except:
18+
- branches
19+
20+
Delivery to hoster:
21+
<<: *delivery_via_git_template
22+
script:
23+
- echo " - Start of CI script"
24+
- date; pwd; ls -lah;
25+
- mkdir -p ~/.ssh
26+
- ls -lah ~
27+
- echo "$DELIVERY_REMOTE_REPO_PRIVATE_KEY" > ~/.ssh/id_rsa
28+
- chmod 0600 ~/.ssh/id_rsa
29+
- ls -lah ~/.ssh
30+
- apk add --no-cache openssh-client git rsync
31+
- ssh-keyscan -H "$DELIVERY_REMOTE_REPO_IP" >> ~/.ssh/known_hosts
32+
- git version
33+
- rsync --version
34+
- export TARGET_GIT_REPO="${DELIVERY_REMOTE_REPO_URL_1}" # Gitlab custom variable to update for each repo to mirror
35+
- echo -e "TARGET_GIT_REPO = $TARGET_GIT_REPO"
36+
- export TARGET_GIT_REPO_BRANCH="${DELIVERY_REMOTE_REPO_BRANCH}" # Gitlab custom variable to update for each repo to mirror
37+
- echo -e "TARGET_GIT_REPO_BRANCH = $TARGET_GIT_REPO_BRANCH"
38+
- export TARGET_GIT_REPO_TYPE="${DELIVERY_REMOTE_REPO_TYPE}"
39+
- echo -e "TARGET_GIT_REPO_TYPE = $TARGET_GIT_REPO_TYPE"
40+
- chmod +x scripts/delivery/deliver_current_tag_via_git.sh
41+
- ./scripts/delivery/deliver_current_tag_via_git.sh
42+
- echo " - End of CI script"
43+
artifacts:
44+
name: "$CI_COMMIT_REF_NAME:$CI_COMMIT_SHA:delivery"
45+
expire_in: 1d
46+
paths:
47+
- ./*
48+
49+
Delivery to repo YYY: # Job can then be duplicated to deliver to multiples repos (just use a different DELIVERY_REMOTE_REPO_URL_N variable for each)
50+
...
51+

scripts/delivery-git/README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Delivering script
2+
3+
## What
4+
5+
- This script deliver the current tag from a repo to another one using a Gitlab CI job, as part of continuous deployments
6+
- You can also deliver to multiple repositories at the same time using multiple jobs in the same pipeline
7+
8+
## Why
9+
10+
Why not use the built-in mirroring functionality Gitlab-ci and other repository services usualy offer ?
11+
12+
- Because it doesn't work when your git repo is protected behind a basic authentication
13+
- Because mirroring to multiple repos at once is sometime a premium (paid) feature
14+
- Because artifacts (downloaded and generated files) are usualy not versioned in git
15+
16+
## Setup
17+
18+
2 files are required :
19+
- `.gitlab-ci.yml`
20+
- `deliver_current_tag_via_git.sh`
21+
22+
1. Define a delivery CI job like "Deliver to repo XXX" in .gitlab-ci.yml, as shown in .gitlab-ci.delivery_example.yml
23+
- To include artefact dependencies, this CI job should be positioned after all dependencies have been built and installed and use the [dependencies](https://docs.gitlab.com/ee/ci/yaml/#dependencies) key word
24+
1. In Gitlab UI, add the following custom CI/CD variables :
25+
- DELIVERY_REMOTE_REPO_IP : IP or domain name of target git repos
26+
- DELIVERY_REMOTE_REPO_PRIVATE_KEY : SSH private key matching public key added to git user
27+
- DELIVERY_REMOTE_REPO_TYPE : Possible values : "PLATFORM.SH" only for now, or leave empty if appropriate
28+
- DELIVERY_REMOTE_REPO_URL_1 : Git repo to which deliver current tag (you can have multiple ones)
29+
- DELIVERY_REMOTE_REPO_BRANCH : Git branch to which deliver current tag
30+
- GIT_USER_EMAIL : Email to be used by git user (used to commit)
31+
- GIT_USER_NAME : Name to be used by git user (used to commit)
32+
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#!/usr/bin/env sh
2+
# Use with Gitlab CI jobs from scripts/delivery/.gitlab-ci.delivery_example.yml
3+
4+
echo -e "\n- Start of delivery script"
5+
# set -x #echo on
6+
7+
# Defining functions # For local use only, NOT FOR USE IN CI
8+
9+
CURRENT_TAG_FUNC()
10+
{
11+
git describe --tags $(git rev-list --tags --max-count=1)
12+
}
13+
14+
# Defining variables
15+
echo -e "- Defining variables...\n"
16+
17+
PACKAGE_DIR=$(pwd)/files_to_be_deployed
18+
echo -e "PACKAGE_DIR = $PACKAGE_DIR"
19+
20+
# TARGET_GIT_REPO=XXX@XXX.git # For local use only, NOT FOR USE IN CI
21+
# For CI use, var is moved to CI job itself, so that same script can be used to clone on multiple repos
22+
echo -e "TARGET_GIT_REPO = $TARGET_GIT_REPO"
23+
24+
# TARGET_GIT_REPO_BRANCH=master # For local use only, NOT FOR USE IN CI
25+
# For CI use, var is moved to CI job itself, so that same script can be used to clone on multiple repos
26+
echo -e "TARGET_GIT_REPO_BRANCH = $TARGET_GIT_REPO_BRANCH"
27+
28+
# TARGET_GIT_REPO_TYPE=GITLAB # For local use only, NOT FOR USE IN CI
29+
# For CI use, var is moved to CI job itself, so that same script can be used to clone on multiple repos
30+
echo -e "TARGET_GIT_REPO_TYPE = $TARGET_GIT_REPO_TYPE"
31+
32+
# CURRENT_TAG=$(CURRENT_TAG_FUNC) # For local use only, NOT FOR USE IN CI
33+
CURRENT_TAG="$CI_COMMIT_REF_NAME" # For CI use only, using Gitlab predefined variable
34+
echo -e "CURRENT_TAG = $CURRENT_TAG"
35+
36+
# GIT_USER_EMAIL="XXX@XXX.com" # For local use only, NOT FOR USE IN CI
37+
echo -e "GIT_USER_EMAIL = $GIT_USER_EMAIL" # For CI use only, using Gitlab custom variable
38+
39+
# GIT_USER_NAME="XXX CI/CD" # For local use only, NOT FOR USE IN CI
40+
echo -e "GIT_USER_NAME = $GIT_USER_NAME" # For CI use only, using Gitlab custom variable
41+
42+
# Preparing delivery dir
43+
echo -e "- Preparing delivery dir...\n"
44+
mkdir "$PACKAGE_DIR"
45+
cd "$PACKAGE_DIR"
46+
47+
# Initialising external git repo
48+
echo -e "- Initialising external git repo...\n"
49+
git init && git config --local core.excludesfile false && git config --local core.fileMode true
50+
git remote add origin $TARGET_GIT_REPO
51+
git pull origin master
52+
git fetch
53+
git checkout $TARGET_GIT_REPO_BRANCH
54+
git config --local user.email "$GIT_USER_EMAIL"
55+
git config --local user.name "$GIT_USER_NAME"
56+
57+
# Deleting files in delivery dir
58+
echo -e "- Deleting files in delivery dir...\n"
59+
set -x #echo on
60+
find -maxdepth 1 ! -name '.git' -exec rm -rv {} \; 1> /dev/null
61+
ls -lah
62+
63+
# Copying files to delivery dir
64+
echo -e "- Copying files to delivery dir...\n"
65+
rsync -av --quiet --progress ../. . --exclude .git/ --exclude files_to_be_deployed/
66+
67+
# Making sure everything needed will be included in commit
68+
echo -e "- Making sure everything needed will be included in commit...\n"
69+
echo -e "-- Deleting all .gitignore files...\n"
70+
mv .gitignore .gitig
71+
find . -name '.gitignore' -type f | wc -l
72+
find . -name '.gitignore' -type f -exec rm {} +
73+
# mv .gitig .gitignore // Note that we don't keep the .gitignore file like we usualy do, all project content must be commited here
74+
75+
echo -e "-- Deleting all .git directories except root one...\n"
76+
mv .git .got
77+
find . -name '.git' -type d | wc -l
78+
find . -name '.git' -type d -exec rm -rf {} +
79+
mv .got .git
80+
81+
# Removing local DB settings from settings.php
82+
sed -i -e "/$databases\['default'\]\['default'\] = array (/,/)/d" web/sites/default/settings.php
83+
# Adding install profile value in settings.php
84+
echo "\$settings['install_profile'] = 'sdd';" >> web/sites/default/settings.php
85+
# Adding settings.local.php to web dir
86+
cp settings/settings.local.php web/sites/default/settings.local.php
87+
sed -i "/settings.local.php';/s/# //g" web/sites/default/settings.php
88+
89+
# Preventing platform.sh error "Application name 'app' is not unique"
90+
if [ "$TARGET_GIT_REPO_TYPE" = "PLATFORM.SH" ]; then
91+
echo -e "- Preventing platform.sh error "Application name 'app' is not unique"...\n"
92+
sed -i "s|name: 'app'|name: 'XXX'|g" ../.platform.app.yaml
93+
fi
94+
# Moving hosting env files back at project root
95+
if [ "$TARGET_GIT_REPO_TYPE" = "GITLAB" ]; then
96+
echo -e "- Moving hosting env files back at project root...\n"
97+
mv .gitlab-ci.yml .gitlab-ci-backup.yml
98+
mv hosting/* hosting/.* .
99+
fi
100+
101+
# Commiting to external repo
102+
echo -e "- Commiting to external repo...\n"
103+
git add -A 1> /dev/null
104+
git status -s
105+
git commit --quiet -m "$CURRENT_TAG"
106+
git push origin $TARGET_GIT_REPO_BRANCH --quiet
107+
git tag "$CURRENT_TAG"
108+
git push --tag
109+
110+
# Cleaning delivery dir
111+
echo -e "- Cleaning delivery dir...\n"
112+
cd ..
113+
rm -rf "$PACKAGE_DIR"
114+
115+
echo -e "- End of delivery script"
116+

0 commit comments

Comments
 (0)