diff --git a/ci/pipeline.yml b/ci/pipeline.yml new file mode 100644 index 0000000..f17baf3 --- /dev/null +++ b/ci/pipeline.yml @@ -0,0 +1,291 @@ +groups: +- name: (( concat "build-" meta.pipeline "-releases" )) + jobs: + - testflight + - rc + - shipit +- name: versioning + jobs: + - major + - minor + - patch +- name: upstream-blobs + jobs: + - (( grab meta.source )) + +meta: + name: (( param "Please name your pipeline" )) + release: (( concat meta.name " Release" )) + target: (( param "Please identify the name of the target Concourse CI" )) + pipeline: (( grab meta.name )) + url: (( param "What is the URL for the Concourse instance this pipeline is located on?" )) + + git: + email: (( param "Please provide the git email for automated commits" )) + name: (( param "Please provide the git name for automated commits" )) + + github: + uri: (( concat "git@github.com:" meta.github.owner "/" meta.github.repo )) + owner: (( param "Please specify the name of the user / organization that owns the Github repository" )) + repo: (( param "Please specify the name of the Github repository" )) + branch: develop + access_token: (( param "Please generate a Personal Access Token and specify it here" )) + release_notes: + repo: "ci-release-notes" + branch: "main" + file: (( concat meta.name "-release-notes.md" )) + uri: (( concat "git@github.com:" meta.github.owner "/" meta.github.release_notes.repo )) + edit: (( concat "https://github.com/" meta.github.owner "/" meta.github.release_notes.repo "/edit/" meta.github.release_notes.branch "/" meta.github.release_notes.file )) + + aws: + bucket: (( concat meta.pipeline "-pipeline" )) + region_name: us-east-1 + access: (( param "Please set your AWS Access Key ID" )) + secret: (( param "Please set your AWS Secret Key ID" )) + +jobs: +- name: testflight + public: true + serial: true + plan: + - get: git + trigger: true + - task: testflight + config: + platform: linux + image_resource: + type: docker-image + source: + repository: registry.ops.scalecf.net/genesis-community/concourse + inputs: + - name: git + run: + path: ./git/ci/scripts/testflight + args: [] + params: + REPO_ROOT: git + BOSH_ENV: ((bosh + BOSH_ENVIRONMENT: (( grab meta.bosh.url )) + BOSH_CA_CERT: (( grab meta.bosh.ca )) + BOSH_CLIENT: (( grab meta.bosh.username )) + BOSH_CLIENT_SECRET: (( grab meta.bosh.password )) + CREDHUB_URL: (( grab meta.credhub.url )) + CREDHUB_CA_CERT: (( grab meta.credhub.ca )) + CREDHUB_CLIENT: (( grab meta.credhub.username )) + CREDHUB_SECRET: (( grab meta.credhub.password )) + BOSH_DEPLOYMENT: (( concat meta.source "-ci" )) + TEST_ERRANDS: ~ + AWS_ACCESS_KEY: (( grab meta.aws.access )) + AWS_SECRET_KEY: (( grab meta.aws.secret )) + MANIFEST_PATH: (( concat "manifests/" meta.source ".yml" )) + MANIFEST_VARS: "--- {}" + MANIFEST_OP_PATHS: "" + +- name: rc + public: true + serial: true + plan: + - in_parallel: + - get: git + trigger: true + passed: [testflight] + - get: version + trigger: false + params: + pre: rc + - task: release-notes + config: + platform: linux + image_resource: + type: docker-image + source: + repository: registry.ops.scalecf.net/genesis-community/concourse + inputs: + - name: git + run: + path: sh + args: + - -ce + - | + cd git + if [ -f ci/release_notes.md ]; then + echo "###### RELEASE NOTES ###############" + echo + cat ci/release_notes.md + echo + echo "########################################" + echo + else + echo "NO RELEASE NOTES HAVE BEEN WRITTEN" + echo "You *might* want to do that before" + echo "hitting (+) on that shipit job..." + echo + fi + - put: version + params: + file: version/number + +- name: shipit + public: true + serial: true + plan: + - in_parallel: + - get: version + passed: [rc] + params: + bump: final + - get: git + passed: [rc] + - task: release + config: + platform: linux + image_resource: + type: docker-image + source: + repository: registry.ops.scalecf.net/genesis-community/concourse + inputs: + - name: version + - name: git + outputs: + - name: gh + - name: pushme + - name: notifications + run: + path: ./git/ci/scripts/shipit + args: [] + params: + REPO_ROOT: git + VERSION_FROM: version/number + RELEASE_ROOT: gh + REPO_OUT: pushme + NOTIFICATION_OUT: notifications + BRANCH: main + GITHUB_OWNER: (( grab meta.github.owner )) + GIT_EMAIL: (( grab meta.git.email )) + GIT_NAME: (( grab meta.git.name )) + AWS_ACCESS_KEY: (( grab meta.aws.access )) + AWS_SECRET_KEY: (( grab meta.aws.secret )) + + - put: upload-git + resource: git + params: + rebase: true + repository: pushme + - put: github-release + resource: (( grab meta.name )) + params: + name: gh/name + tag: gh/tag + body: gh/notes.md + globs: [gh/artifacts/*] + - put: version-bump-patch + resource: version + params: + bump: patch + +- name: patch + public: true + plan: + - get: version + params: + bump: patch + - put: version + params: + file: version/number + +- name: minor + public: true + plan: + - do: + - get: version + params: + bump: minor + - put: version + params: + file: version/number + +- name: major + public: true + plan: + - get: version + params: + bump: major + - put: version + params: + file: version/number + + +- name: (( grab meta.source )) + public: true + plan: + - in_parallel: + - get: git + - get: (( grab meta.source )) + trigger: true + params: + globs: [ (( concat meta.source "-*-linux-amd64" )) ] + - task: (( concat "update-" meta.source )) + config: + platform: linux + image_resource: + type: docker-image + source: + repository: registry.ops.scalecf.net/genesis-community/concourse + inputs: + - name: git + - name: (( grab meta.source )) + outputs: + - name: pushme + run: + path: ./git/ci/scripts/update-blob + params: + REPO_ROOT: git + REPO_OUT: pushme + BLOB_DIR: (( grab meta.source )) + BLOB_NAME: (( grab meta.source )) + BLOB_BINARY: (( concat meta.source "-*-linux-amd64" )) + BLOB_DESTINATION: (( concat meta.source "/" meta.source )) + BLOB_CLEANUP: (( concat meta.source "/" meta.source )) + GIT_NAME: (( grab meta.git.name )) + GIT_EMAIL: (( grab meta.git.email )) + AWS_ACCESS_KEY: (( grab meta.aws.access )) + AWS_SECRET_KEY: (( grab meta.aws.secret )) + BRANCH: main + - put: git + params: + rebase: true + repository: pushme/git + +resources: +- name: git + type: git + source: + uri: (( concat "https://github.com/" meta.github.owner "/" meta.github.repo ".git" )) + branch: (( grab meta.github.branch )) + username: (( grab meta.github.username )) + password: (( grab meta.github.access_token )) + +- name: version + type: semver + source: + driver: s3 + bucket: (( grab meta.aws.bucket )) + region_name: (( grab meta.aws.region_name )) + key: (( concat meta.github.source-repo "/boshrelease-version" )) + access_key_id: (( grab meta.aws.access )) + secret_access_key: (( grab meta.aws.secret )) + initial_version: "1.2.0" + +- name: (( grab meta.name )) + type: github-release + source: + user: (( grab meta.github.owner )) + repository: (( grab meta.github.repo )) + access_token: (( grab meta.github.access_token )) + +- name: (( grab meta.source )) + type: github-release + source: + user: (( grab meta.github.owner )) + repository: (( grab meta.github.source-repo )) + access_token: (( grab meta.github.access_token )) diff --git a/ci/repipe b/ci/repipe new file mode 100755 index 0000000..bc8a661 --- /dev/null +++ b/ci/repipe @@ -0,0 +1,115 @@ +#!/bin/bash +# +# ci/repipe +# +# Script for merging together pipeline configuration files +# (via Spruce!) and configuring Concourse. +# +# author: James Hunt +# Dennis Bell +# created: 2016-03-04 + +need_command() { + local cmd=${1:?need_command() - no command name given} + + if [[ ! -x "$(command -v $cmd)" ]]; then + echo >&2 "${cmd} is not installed." + if [[ "${cmd}" == "spruce" ]]; then + echo >&2 "Please download it from https://github.com/geofffranks/spruce/releases" + fi + exit 2 + fi +} + +NO_FLY= +SAVE_MANIFEST= +VALIDATE_PIPELINE= +NON_INTERACTIVE= + +cleanup() { + rm -f save-manifest.yml + if [[ -n ${SAVE_MANIFEST} && -e .deploy.yml ]]; then + mv .deploy.yml save-manifest.yml + fi + rm -f .deploy.yml +} + +usage() { + echo Command line arguments: + echo "no-fly Do not execute any fly commands" + echo "save-manifest Save manifest to file save-manifest" + echo "validate Validatei pipeline instead of set pipeline" + echo "validate-strict Validate pipeline with strict mode" + echo "non-interactive Run set-pipeline in non-interactive mode" +} + +for arg do + case "${arg}" in + no-fly|no_fly) NO_FLY="yes" ;; + save-manifest|save_manifest) SAVE_MANIFEST="yes" ;; + validate) VALIDATE_PIPELINE="normal" ;; + validate-strict|validate_strict) VALIDATE_PIPELINE="strict" ;; + non-interactive|non_interactive) NON_INTERACTIVE="--non-interactive" ;; + help|-h|--help) usage; exit 0 ;; + *) echo Invalid argument + usage + exit 1 + esac +done + +cd $(dirname $BASH_SOURCE[0]) +echo "Working in $(pwd)" +need_command spruce + +# Allow for target-specific settings +settings_file="$(ls -1 settings.yml ${CONCOURSE_TARGET:+"settings-${CONCOURSE_TARGET}.yml"} 2>/dev/null | tail -n1)" +if [[ -z "$settings_file" ]] +then + echo >&2 "Missing local settings in ci/settings.yml${CONCOURSE_TARGET:+" or ci/settings-${CONCOURSE_TARGET}.yml"}!" + exit 1 +fi + +echo >&2 "Using settings found in ${settings_file}" + +set -e +trap "cleanup" QUIT TERM EXIT INT +# New style: spruce merge pipeline/base.yml pipeline/jobs/*.yml pipeline/resources/*.yml ${settings_file} > .deploy.yml +spruce merge pipeline.yml ${settings_file} > .deploy.yml +PIPELINE=$(spruce json .deploy.yml | jq -r '.meta.pipeline // ""') +if [[ -z ${PIPELINE} ]]; then + echo >&2 "Missing pipeline name in ci/settings.yml!" + exit 1 +fi + +TARGET_FROM_SETTINGS=$(spruce json .deploy.yml | jq -r '.meta.target // ""') +if [[ -z ${CONCOURSE_TARGET} ]]; then + TARGET=${TARGET_FROM_SETTINGS} +elif [[ "$CONCOURSE_TARGET" != "$TARGET_FROM_SETTINGS" ]] +then + echo >&2 "Target in {$settings_file} differs from target in \$CONCOURSE_TARGET" + echo >&2 " \$CONCOURSE_TARGET: $CONCOURSE_TARGET" + echo >&2 " Target in file: $TARGET_FROM_SETTINGS" + exit 1 +else + TARGET=${CONCOURSE_TARGET} +fi + +if [[ -z ${TARGET} ]]; then + echo >&2 "Missing Concourse Target in ci/settings.yml!" + exit 1 +fi + +fly_cmd="${FLY_CMD:-fly}" + +[[ -n ${NO_FLY} ]] && { echo no fly execution requested ; exit 0; } + +case "${VALIDATE_PIPELINE}" in + normal) fly_opts="validate-pipeline" ;; + strict) fly_opts="validate-pipeline --strict" ;; + *) fly_opts="set-pipeline ${NON_INTERACTIVE} --pipeline ${PIPELINE}" ;; +esac + +set +x +$fly_cmd --target ${TARGET} ${fly_opts} --config .deploy.yml +[[ -n ${VALIDATE_PIPELINE} ]] && exit 0 +$fly_cmd --target ${TARGET} pause-pipeline --pipeline ${PIPELINE} diff --git a/ci/scripts/bump-dependent-release b/ci/scripts/bump-dependent-release new file mode 100755 index 0000000..a0c5f9b --- /dev/null +++ b/ci/scripts/bump-dependent-release @@ -0,0 +1,81 @@ +#!/bin/bash + +# The goal of this script is to retain the pretty nature of manifests, whilst updating +# the "releases:" section. +# +# If we use `spruce merge` to do the job, the entire manifest will be reordered - +# keys will be sorted alphabetically. Comments will be lost. +# +# Instead, we assume that "releases:" is the last section of the manifest. +set -e + +: ${REPO_ROOT:?required} +: ${REPO_OUT:?required} +: ${RELEASE:?required} +: ${NAME:?required} + +if [[ ! -f ${RELEASE}/version ]]; then + echo "Director ${RELEASE} must have file /version" + exit 1 +fi + +git clone ${REPO_ROOT} ${REPO_OUT} + +version=$(cat ${RELEASE}/version) + +# So, this is a nested bash/spruce/jq combo. +# What is happening here is that the "releases:" section of each deployment manifest +# is being updated with the new version/sha1 for the release. +# +# We use "spruce json manifest.yml | jq '.releases'" to extract the existing releases array +# and the '.releases | map(if .name == $name)' will modify a specific element of the array +# +# This gives us a modified "releases: [{...}, {...}]" segment of the final deployment manifest. +# We now need to merge this back into the original manifest. +# +# But, I don't want to just use `spruce merge` for this as it will reorder the manifest and +# make it ugly. If I didn't care about the manifest's aesthetics then this whole script +# would be simpler. I want the original layout of the manifest to be retained; and so +# we will just chomp out the original "releases:" section at the end of the file and +# paste in the updated releases section. +function bump_version { + manifest_path=$1 + releases_updated=$(spruce merge < $manifest_path <>ci/release_notes.md +* Bumped ${NAME} to v${version} +EOF + + +if [[ -z $(git config --global user.email) ]]; then + git config --global user.email "${GIT_EMAIL}" +fi +if [[ -z $(git config --global user.name) ]]; then + git config --global user.name "${GIT_NAME}" +fi + +git merge --no-edit ${BRANCH} +git add -A +git status +git commit -m "bump ${NAME} v${version}" diff --git a/ci/scripts/export-release b/ci/scripts/export-release new file mode 100755 index 0000000..c834c2e --- /dev/null +++ b/ci/scripts/export-release @@ -0,0 +1,71 @@ +#!/bin/bash + +set -eu + +: ${BOSH_ENVIRONMENT:?required} +: ${BOSH_CA_CERT:?required} +: ${BOSH_CLIENT:?required} +: ${BOSH_CLIENT_SECRET:?required} + +# +# stemcell metadata/upload +# + +STEMCELL_CPI=${STEMCELL_CPI:-warden-boshlite} +STEMCELL_OS=${STEMCELL_OS:-ubuntu-xenial} +STEMCELL_VERSION=$(cat stemcell/version) + +if [[ $(bosh stemcells --json | jq -r ".Tables[0].Rows[] | select(.os == \"${STEMCELL_OS}\") | .version | test(\"${STEMCELL_VERSION}\")" | grep true | uniq) != "true" ]]; then + # https://bosh.io/d/stemcells/bosh-warden-boshlite-ubuntu-trusty-go_agent?v=3586.7 + bosh -n upload-stemcell "https://bosh.io/d/stemcells/bosh-${STEMCELL_CPI}-${STEMCELL_OS}-go_agent?v=${STEMCELL_VERSION}" +fi + +# +# release metadata/upload +# + +cd release +tar -xzf *.tgz $( tar -tzf *.tgz | grep 'release.MF' ) +RELEASE_NAME=$( grep -E '^name: ' release.MF | awk '{print $2}' | tr -d "\"'" ) +RELEASE_VERSION=$( grep -E '^version: ' release.MF | awk '{print $2}' | tr -d "\"'" ) + +bosh -n upload-release *.tgz +cd ../ + +# +# compilation deployment +# + +cat > manifest.yml < +# created: 2016-03-30 + +set -eu + +header() { + echo + echo "###############################################" + echo + echo $* + echo +} + +: ${REPO_ROOT:?required} +: ${RELEASE_ROOT:?required} +: ${REPO_OUT:?required} +: ${BRANCH:?required} +: ${GITHUB_OWNER:?required} +: ${VERSION_FROM:?required} +: ${AWS_ACCESS_KEY:?required} +: ${AWS_SECRET_KEY:?required} +: ${GIT_EMAIL:?required} +: ${GIT_NAME:?required} + +if [[ ! -f ${VERSION_FROM} ]]; then + echo >&2 "Version file (${VERSION_FROM}) not found. Did you misconfigure Concourse?" + exit 2 +fi +VERSION=$(cat ${VERSION_FROM}) +if [[ -z ${VERSION} ]]; then + echo >&2 "Version file (${VERSION_FROM}) was empty. Did you misconfigure Concourse?" + exit 2 +fi + +if [[ ! -f ${REPO_ROOT}/ci/release_notes.md ]]; then + echo >&2 "ci/release_notes.md not found. Did you forget to write them?" + exit 1 +fi + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +############################################################### + +git clone ${REPO_ROOT} ${REPO_OUT} + +pushd ${REPO_OUT} +RELEASE_NAME=$(bosh int config/final.yml --path /final_name) + +cat > config/private.yml < ${RELEASE_ROOT}/tag +echo "v${VERSION}" > ${RELEASE_ROOT}/name +mv ${REPO_OUT}/releases/*/*-${VERSION}.tgz ${RELEASE_ROOT}/artifacts +mv ${REPO_OUT}/ci/release_notes.md ${RELEASE_ROOT}/notes.md +cat >> ${RELEASE_ROOT}/notes.md < ${RELEASE_ROOT}/notification < New ${RELEASE_NAME} v${VERSION} released! +EOF + + +header "Update git repo with final release..." +if [[ -z $(git config --global user.email) ]]; then + git config --global user.email "${GIT_EMAIL}" +fi +if [[ -z $(git config --global user.name) ]]; then + git config --global user.name "${GIT_NAME}" +fi + +pushd $REPO_OUT +$DIR/update-manifest-release $RELEASE_NAME $VERSION $RELEASE_URL $RELEASE_SHA1 + +git merge --no-edit ${BRANCH} +git add -A +git status +git commit -m "release v${VERSION}" +popd + +cat > ${NOTIFICATION_OUT:-notifications}/message <. +EOS diff --git a/ci/scripts/testflight b/ci/scripts/testflight new file mode 100755 index 0000000..ddc00e0 --- /dev/null +++ b/ci/scripts/testflight @@ -0,0 +1,170 @@ +#!/bin/bash +# +# ci/scripts/testflight +# +# Script for testing a BOSH release using bosh +# +# author: James Hunt + +set -eu + +: ${BOSH_ENVIRONMENT:?required} +: ${BOSH_CA_CERT:?required} +: ${BOSH_CLIENT:?required} +: ${BOSH_CLIENT_SECRET:?required} +: ${BOSH_DEPLOYMENT:?required} +: ${MANIFEST_PATH:?required} +: ${AWS_ACCESS_KEY:?required} +: ${AWS_SECRET_KEY:?required} +DEBUG=${DEBUG:-} +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +header() { + echo + echo "###############################################" + echo + echo $* + echo +} + +delete_deployment() { + header "Cleaning up deployment..." + bosh -n delete-deployment --force +} +trap "echo; echo; echo; sleep 10; delete_deployment" EXIT SIGINT SIGTERM + + +cd ${REPO_ROOT:?required} +header "Pulling in any git submodules..." +git submodule update --init --recursive --force + +header "Confirming testflight inputs" + +echo "Confirming deployment manifest ${MANIFEST_PATH} exists" +if [[ ! -f ${MANIFEST_PATH} ]]; then + echo "Deployment manifest ${MANIFEST_PATH} does not exist" + exit 1 +fi + +echo "Confirming that \$MANIFEST_VARS is valid" +mkdir -p tmp + +# $MANIFEST_VARS can either be "key: value" or "key=value" +# and will be converted to "key: value" YAML +echo "${MANIFEST_VARS:-"{} ---"}" | sed -e "s/ *= */: /g" > tmp/vars.yml +if [[ ! -z $DEBUG ]]; then + echo "Variables passed to deployment manifest:" + cat tmp/vars.yml +fi +# convert YAML to JSON to check YAML validity +spruce json tmp/vars.yml > /dev/null + +echo "Confirming each operator file exists: ${MANIFEST_OP_PATHS:-ok, none specified.}" +op_patch_file_errors= +for op_patch_file in ${MANIFEST_OP_PATHS//,/ } ; do + if [[ ! -f $op_patch_file ]]; then + op_patch_file_errors=1 + echo "Operator file missing: ${op_patch_file}" + fi +done +if [[ ! -z ${op_patch_file_errors} ]]; then + exit 1 +fi + +$DIR/wait-until-proxy-bosh-cf-running +if [[ "${PROXY_IP:-X}" != "X" ]] ; then export BOSH_ALL_PROXY=socks5://localhost:9999 ; fi + +delete_deployment + +header "Creating candidate BOSH release..." +bosh -n reset-release # in case dev_releases/ is in repo accidentally + +cat > config/private.yml < tmp/deployment.yml <> tmp/deployment.yml <> tmp/deployment.yml < tmp/manifest.yml + +bosh -n deploy tmp/manifest.yml + +TEST_ERRAND=${TEST_ERRAND:-} # backwards compatibility +TEST_ERRANDS=${TEST_ERRANDS:-$TEST_ERRAND} +if [[ -n ${TEST_ERRANDS} ]]; then + for errand in ${TEST_ERRANDS}; do + header "Running '${errand}' errand" + bosh -n run-errand ${errand} + done +else + echo "No test errands specified, skipping." +fi + +echo +echo "SUCCESS" +exit 0 diff --git a/ci/scripts/update-blob b/ci/scripts/update-blob new file mode 100755 index 0000000..f23d825 --- /dev/null +++ b/ci/scripts/update-blob @@ -0,0 +1,61 @@ +#!/bin/bash + +set -e + +: ${BLOB_DIR:?required} +: ${BLOB_NAME:?required} +: ${BLOB_BINARY:?required} +: ${BLOB_CLEANUP:?required} +: ${BLOB_DESTINATION:?required} + +VERSION=$(cat ${BLOB_DIR}/version) + +pushd ${REPO_ROOT:?required} + +cat <config/private.yml +--- +blobstore: + provider: s3 + options: + access_key_id: ${AWS_ACCESS_KEY:?required} + secret_access_key: ${AWS_SECRET_KEY:?required} +EOF + +blobs_to_remove=$(spruce json config/blobs.yml | jq -r "keys[] | select(test(\"${BLOB_CLEANUP}\"))") +if [[ ! -z $blobs_to_remove ]]; then + echo "$blobs_to_remove" | xargs -L1 bosh remove-blob +fi + +# expand ${VERSION} env var into file path +eval "blob_destination=${BLOB_DESTINATION}" +bosh add-blob ../${BLOB_DIR}/${BLOB_BINARY} "${blob_destination}" +bosh -n upload-blobs +rm config/private.yml +popd + +if [[ -n "$(cd ${REPO_ROOT}; git status --porcelain)" ]]; then + pushd ${REPO_ROOT} + cat <>ci/release_notes.md + +# ${BLOB_NAME} +Bumped ${BLOB_URL} to v${VERSION} +EOF + popd + + # GIT! + if [[ -z $(git config --global user.email) ]]; then + git config --global user.email "ci@starkandwayne.com" + fi + if [[ -z $(git config --global user.name) ]]; then + git config --global user.name "CI Bot" + fi + + (cd ${REPO_ROOT} + git merge --no-edit ${BRANCH} + git add -A + git status + git commit -m "Bumped ${BLOB_NAME} to v${VERSION}") +fi + +# so that future steps in the pipeline can push our changes +cp -a ${REPO_ROOT} ${REPO_OUT} diff --git a/ci/scripts/update-manifest-compiled-release b/ci/scripts/update-manifest-compiled-release new file mode 100755 index 0000000..33107c7 --- /dev/null +++ b/ci/scripts/update-manifest-compiled-release @@ -0,0 +1,63 @@ +#!/bin/bash + +# The goal of this script is to retain the pretty nature of manifests, whilst updating +# the "releases:" section with a stemcell-restricted compiled release +# +# If we use `spruce merge` to do the job, the entire manifest will be reordered - +# keys will be sorted alphabetically. Comments will be lost. +# +# Instead, we assume that "releases:" is the last section of the manifest. +set -e + +NAME=$1 +VERSION=$2 +RELEASE_TGZ_URL=$3 +RELEASE_TGZ_SHA1=$4 +STEMCELL_OS=$5 +STEMCELL_VERSION=$6 + +if [[ "${STEMCELL_VERSION:-X}" == "X" ]]; then + echo "USAGE: update-manifest-release NAME VERSION URL SHA1 STEMCELL_OS STEMCELL_VERSION" + exit 1 +fi +: ${REPO_ROOT:?required} +: ${REPO_OUT:?required} + +# So, this is a nested bash/spruce/jq combo. +# What is happening here is that the "releases:" section of each deployment manifest +# is being updated with the new version/sha1 for the release. +# +# We use "spruce json manifest.yml | jq '.releases'" to extract the existing releases array +# and the '.releases | map(if .name == $name)' will modify a specific element of the array +# +# This gives us a modified "releases: [{...}, {...}]" segment of the final deployment manifest. +# We now need to merge this back into the original manifest. +# +# But, I don't want to just use `spruce merge` for this as it will reorder the manifest and +# make it ugly. If I didn't care about the manifest's aesthetics then this whole script +# would be simpler. I want the original layout of the manifest to be retained; and so +# we will just chomp out the original "releases:" section at the end of the file and +# paste in the updated releases section. +function bump_version { + manifest_path=$1 + releases_updated=$(spruce merge < $manifest_path < $manifest_path < proxy/ssh/private_key + chmod 600 proxy/ssh/private_key + + header "Checking jumpbox available..." + set +e + until ssh ${PROXY_USERNAME}@${PROXY_IP} -i proxy/ssh/private_key \ + -o BatchMode=yes -o StrictHostKeyChecking=no -o ConnectTimeout=60 \ + "whoami" + do + echo "Waiting until jumpbox/proxy available..." + done + set -e + + header "Starting socks5 proxy..." + ssh ${PROXY_USERNAME}@${PROXY_IP} -i proxy/ssh/private_key -N -D 9999 & + sleep 10 + + echo BOSH_ALL_PROXY=socks5://localhost:9999 + export BOSH_ALL_PROXY=socks5://localhost:9999 +fi + +header "Checking bosh available..." +until bosh env; do + echo "Waiting until bosh available..." + sleep 60 +done + +if [[ -f git/tmp/vars.yml ]]; then + cf_api_url=$(bosh int git/tmp/vars.yml --path /cf-api-url) + if [[ "${cf_api_url:-X}" != "X" ]]; then + header "Checking Cloud Foundry available..." + until cf api $cf_api_url --skip-ssl-validation; do + echo "Waiting until Cloud Foundry available..." + sleep 60 + done + fi +fi + +echo +echo diff --git a/ci/settings.yml b/ci/settings.yml new file mode 100644 index 0000000..048a4ae --- /dev/null +++ b/ci/settings.yml @@ -0,0 +1,37 @@ +--- +meta: + name: (( concat meta.source "-boshrelease" )) + source: ocf-scheduler + release: OCF Scheduler Bosh Release + target: pipes/cloudfoundry-community + url: https://pipes.scalecf.com + + bosh: + url: ((thunder-dome.url)) + username: ((thunder-dome.username)) + password: ((thunder-dome.password)) + ca: ((thunder-dome.ca-certificate)) + + credhub: + url: ((thunder-dome-credhub.url)) + username: ((thunder-dome-credhub.username)) + password: ((thunder-dome-credhub.password)) + ca: ((thunder-dome-credhub.ca-certificate)) + + aws: + bucket: ((concat meta.source "-pipeline" )) + access: ((aws.access_key_id)) + secret: ((aws.secret_access_key)) + + git: + name: ((github.name)) + email: ((github.email)) + + github: + owner: cloudfoundry-community + source-repo: (( grab meta.source )) + repo: (( grab meta.name )) + username: ((github.username)) + branch: main + access_token: ((github.access_token_rw)) +