Skip to content

Commit b9c230d

Browse files
valeriapchristianang
authored andcommitted
Add Create Final Release Job in CI
[#104050546] Signed-off-by: Christian Ang <[email protected]>
1 parent 00c7a16 commit b9c230d

File tree

5 files changed

+412
-0
lines changed

5 files changed

+412
-0
lines changed

ci/pipelines/postgres.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ groups:
55
- deploy-with-diego
66
- test-with-diego
77
- delete-deployments
8+
- create-final-release
89

910
resources:
1011
- name: cf-release
@@ -33,6 +34,19 @@ resources:
3334
ignore_paths: [.final_builds, releases]
3435
uri: https://github.com/cloudfoundry/diego-release.git
3536

37+
- name: oss-s3-buckets-stack
38+
type: git
39+
source:
40+
branch: master
41+
private_key: {{oss-s3-buckets-stack-private-key}}
42+
uri: [email protected]:cloudfoundry/oss-s3-buckets-stack.git
43+
44+
- name: postgres-release-master
45+
type: git
46+
source:
47+
uri: https://github.com/cloudfoundry/postgres-release.git
48+
branch: master
49+
3650
jobs:
3751
- name: deploy-with-cf
3852
serial_groups: [cf]
@@ -114,3 +128,27 @@ jobs:
114128
BOSH_DIRECTOR: {{postgres_cf_bosh_director}}
115129
BOSH_USER: {{postgres_cf_bosh_user}}
116130
BOSH_PASSWORD: {{postgres_cf_bosh_password}}
131+
132+
- name: create-final-release
133+
serial_groups: [cf]
134+
plan:
135+
- aggregate:
136+
- get: postgres-release
137+
resource: postgres-release-develop
138+
- get: oss-s3-buckets-stack
139+
resource: oss-s3-buckets-stack
140+
- get: release-repo
141+
resource: postgres-release-develop
142+
passed: [delete-deployments]
143+
trigger: true
144+
- get: release-repo-master
145+
resource: postgres-release-master
146+
- task: create-final-release
147+
file: postgres-release/ci/scripts/create-final-release/task.yml
148+
params:
149+
RELEASE_NAME: postgres
150+
#- put: postgres-release-master
151+
#params:
152+
#repository: final-release-repo
153+
#tag: final-release-repo/version_number
154+
#tag_prefix: v
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
#!/bin/bash -exu
2+
3+
function validate_arguments() {
4+
if [ $# -ne 3 ]; then
5+
echo "Expected 3 argument (release_name path_to_aws_credentials_dir path_to_config_dir) received $#"
6+
exit 1
7+
fi
8+
}
9+
10+
function check_dependencies() {
11+
command -v aws >/dev/null || { echo "aws is required"; exit 1; }
12+
command -v jq >/dev/null || { echo "jq is required"; exit 1; }
13+
}
14+
15+
function load_credentials() {
16+
set +x
17+
source "${credentials_dir}/aws_environment"
18+
19+
if [[ -z "${AWS_DEFAULT_REGION}" ]]; then
20+
echo "AWS_DEFAULT_REGION is not set"
21+
exit 1
22+
fi
23+
24+
if [[ -z "${AWS_ACCESS_KEY_ID}" ]]; then
25+
echo "AWS_DEFAULT_REGION is not set"
26+
exit 1
27+
fi
28+
29+
if [[ -z "${AWS_SECRET_ACCESS_KEY}" ]]; then
30+
echo "AWS_DEFAULT_REGION is not set"
31+
exit 1
32+
fi
33+
34+
set -x
35+
}
36+
37+
function apply_cloudformation_template() {
38+
local release_name
39+
release_name="${1}"
40+
41+
local script_dir
42+
script_dir="${2}"
43+
44+
if aws cloudformation describe-stacks --stack-name "${release_name}-buckets" > /dev/null; then
45+
apply_stack_operation update "${release_name}" "${script_dir}" || true
46+
else
47+
apply_stack_operation create "${release_name}" "${script_dir}"
48+
fi
49+
50+
wait_on_cloudformation "${release_name}"
51+
check_final_cloudformation_state "${release_name}"
52+
}
53+
54+
function apply_stack_operation() {
55+
local operation
56+
operation="${1}"
57+
58+
local release_name
59+
release_name="${2}"
60+
61+
local script_dir
62+
script_dir="${3}"
63+
64+
ls -a ${script_dir}/..
65+
ls -a ${script_dir}/../templates
66+
ls -a ${script_dir}/../templates/final-release
67+
68+
aws cloudformation "${operation}-stack" \
69+
--stack-name "${release_name}-buckets" \
70+
--parameters "ParameterKey=BucketName,ParameterValue=${release_name}-release-blobs" \
71+
--template-body "file://${script_dir}/../templates/final-release/bucket.json" \
72+
--capabilities CAPABILITY_IAM > /dev/null
73+
}
74+
75+
function cloudformation_stack_status() {
76+
local release_name
77+
release_name="${1}"
78+
79+
local status
80+
status="$(aws cloudformation describe-stacks --stack-name "${release_name}-buckets" | jq -r .Stacks[].StackStatus)"
81+
82+
printf "%s" "${status}"
83+
}
84+
85+
function wait_on_cloudformation() {
86+
local release_name
87+
release_name="${1}"
88+
89+
local half_an_hour
90+
half_an_hour="$((30 * 60))"
91+
92+
local deadline_in_seconds
93+
deadline_in_seconds=$(($(date +%s) + ${half_an_hour}))
94+
95+
while cloudformation_stack_status "${release_name}" | grep IN_PROGRESS ; do
96+
echo "CloudFormation stack '${release_name}-buckets' still in progress..."
97+
98+
local remaining_time_in_seconds
99+
remaining_time_in_seconds="$((deadline_in_seconds - $(date +%s)))"
100+
101+
if [ "${remaining_time_in_seconds}" -gt 0 ]; then
102+
echo " Waiting ${remaining_time_in_seconds} more seconds."
103+
sleep 15
104+
else
105+
echo " Waited ${half_an_hour} seconds, aborting."
106+
exit 1
107+
fi
108+
done
109+
}
110+
111+
function check_final_cloudformation_state() {
112+
local release_name
113+
release_name="${1}"
114+
115+
local status
116+
status="$(cloudformation_stack_status "${release_name}")"
117+
118+
if echo "${status}" | grep ROLLBACK ; then
119+
echo "CloudFormation failed to apply template: ${status}"
120+
exit 1
121+
fi
122+
123+
if ! echo "${status}" | grep COMPLETE ; then
124+
echo "CloudFormation failed to apply template: ${status}"
125+
exit 1
126+
fi
127+
}
128+
129+
function write_private_yaml() {
130+
local release_name
131+
release_name="${1}"
132+
133+
local credentials_dir
134+
credentials_dir="${2}"
135+
136+
local release_config_dir
137+
release_config_dir="${3}"
138+
139+
local bucket_output
140+
bucket_output="${credentials_dir}/bucket.json"
141+
142+
aws cloudformation describe-stacks --stack-name "${release_name}-buckets" > "${bucket_output}"
143+
144+
local access_key_id
145+
local secret_access_key
146+
147+
set +x
148+
secret_access_key="$(jq -e -r ".Stacks[0].Outputs[0].OutputValue" "${bucket_output}")"
149+
access_key_id="$(jq -e -r ".Stacks[0].Outputs[1].OutputValue" "${bucket_output}")"
150+
set -x
151+
152+
cat > "${release_config_dir}/private.yml" <<EOF
153+
---
154+
blobstore:
155+
s3:
156+
access_key_id: ${access_key_id}
157+
secret_access_key: ${secret_access_key}
158+
EOF
159+
160+
rm "${bucket_output}"
161+
}
162+
163+
function main() {
164+
local script_dir
165+
script_dir="$(cd "$(dirname "$0")" && pwd)"
166+
167+
validate_arguments "${@}"
168+
169+
local release_name
170+
release_name="${1}"
171+
172+
local credentials_dir
173+
credentials_dir="${2}"
174+
175+
local release_config_dir
176+
release_config_dir="${3}"
177+
178+
check_dependencies
179+
load_credentials "${credentials_dir}"
180+
apply_cloudformation_template "${release_name}" "${script_dir}"
181+
write_private_yaml "${release_name}" "${credentials_dir}" "${release_config_dir}"
182+
}
183+
184+
main "${@}"
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#!/bin/bash -exu
2+
3+
# Cannot set -u before sourcing .bashrc because of all
4+
# the unbound variables in things beyond our control.
5+
set +u
6+
source ~/.bashrc
7+
set -u
8+
9+
function main() {
10+
local root_dir
11+
root_dir="${PWD}"
12+
13+
local release_name
14+
release_name="${1}"
15+
16+
local master_branch
17+
master_branch="${2}"
18+
19+
configure_bucket "${release_name}"
20+
create_and_commit "${root_dir}" "${release_name}" "${master_branch}"
21+
copy_to_output "${root_dir}"
22+
}
23+
24+
function configure_bucket() {
25+
local release_name
26+
release_name="${1}"
27+
28+
set +x
29+
./postgres-release/ci/scripts/configure_final_release_bucket "${release_name}" ./oss-s3-buckets-stack ./release-repo/config
30+
set -x
31+
}
32+
33+
function create_and_commit() {
34+
local root_dir
35+
root_dir="${1}"
36+
37+
local release_name
38+
release_name="${2}"
39+
40+
local master_branch
41+
master_branch="${3}"
42+
43+
pushd "${root_dir}/release-repo" > /dev/null
44+
git config user.name "CF MEGA BOT"
45+
git config user.email "[email protected]"
46+
47+
git remote add -f master-repo "${root_dir}/release-repo-master"
48+
git merge "master-repo/${master_branch}" -m 'Merge with master'
49+
50+
local exit_status
51+
for i in {1..5}; do
52+
bosh -n create release --with-tarball --final
53+
exit_status="${PIPESTATUS[0]}"
54+
55+
if [[ "${exit_status}" == "0" ]]; then
56+
break
57+
fi
58+
done
59+
60+
if [[ "${exit_status}" != "0" ]]; then
61+
echo "Failed to Create ${release_name} Release"
62+
exit "${exit_status}"
63+
fi
64+
65+
local new_release_version
66+
new_release_version="$(find releases -regex ".*${release_name}-[0-9]*.yml" | egrep -o "${release_name}-[0-9]+" | egrep -o "[0-9]+" | sort -n | tail -n 1)"
67+
68+
git add .final_builds releases
69+
git commit -m "Final release ${new_release_version}"
70+
71+
echo "${new_release_version}" > version_number
72+
popd > /dev/null
73+
}
74+
75+
function copy_to_output() {
76+
local root_dir
77+
root_dir="${1}"
78+
79+
shopt -s dotglob
80+
cp -R "${root_dir}/release-repo/"* "${root_dir}/final-release-repo"
81+
}
82+
83+
main "${RELEASE_NAME}" "${MASTER_BRANCH:-"master"}"
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
platform: linux
3+
4+
image: docker:///cfinfrastructure/deployment
5+
6+
inputs:
7+
- name: postgres-release
8+
- name: oss-s3-buckets-stack
9+
- name: release-repo
10+
- name: release-repo-master
11+
12+
outputs:
13+
- name: final-release-repo
14+
15+
run:
16+
path: postgres-release/ci/scripts/create-final-release/task.sh
17+
18+
params:
19+
RELEASE_NAME:
20+
MASTER_BRANCH:

0 commit comments

Comments
 (0)