From 95002d898efaf957a364a0e102c1c6ec79539e97 Mon Sep 17 00:00:00 2001 From: Chris Alfano Date: Thu, 26 Aug 2021 18:11:27 +0000 Subject: [PATCH 1/7] chore(deps): bump laddr to v3.0.4 --- .holo/sources/laddr.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.holo/sources/laddr.toml b/.holo/sources/laddr.toml index eb6ab5fa..bad06192 100644 --- a/.holo/sources/laddr.toml +++ b/.holo/sources/laddr.toml @@ -1,3 +1,3 @@ [holosource] url = "https://github.com/CodeForPhilly/laddr" -ref = "refs/tags/v3.0.3" +ref = "refs/tags/v3.0.4" From c21e84ee9fb0c4f9dd6b865c1e17a870a76be034 Mon Sep 17 00:00:00 2001 From: Chris Alfano Date: Thu, 26 Aug 2021 18:14:56 +0000 Subject: [PATCH 2/7] feat(ci): add k8s deploy workflows --- .github/workflows/k8s-deploy.yml | 234 ++++++++++++++++++++++++++++++ .github/workflows/k8s-destroy.yml | 38 +++++ 2 files changed, 272 insertions(+) create mode 100644 .github/workflows/k8s-deploy.yml create mode 100644 .github/workflows/k8s-destroy.yml diff --git a/.github/workflows/k8s-deploy.yml b/.github/workflows/k8s-deploy.yml new file mode 100644 index 00000000..67ae0089 --- /dev/null +++ b/.github/workflows/k8s-deploy.yml @@ -0,0 +1,234 @@ +name: Deploy K8s Preview + +on: + pull_request: + branches: [ develop ] + types: [ opened, reopened, synchronize ] + push: + branches: [ develop ] + +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + DOCKER_REGISTRY: ghcr.io + DOCKER_PACKAGE: codeforphilly-composite + + KUBE_CONFIG_DATA: ${{ secrets.KUBECONFIG_BASE64 }} + KUBE_NAMESPACE: codeforphilly + KUBE_HOSTNAME: codeforphilly.sandbox.k8s.phl.io + + DATABASE_NAME: codeforphilly + + HAB_LICENSE: accept-no-persist + HAB_ORIGIN: codeforphilly + +jobs: + + k8s-deploy: + runs-on: ubuntu-latest + steps: + + - name: Cancel superseded runs + uses: styfle/cancel-workflow-action@0.7.0 + with: + access_token: ${{ secrets.GITHUB_TOKEN }} + + - name: Configure environment + run: | + if [ "${GITHUB_EVENT_NAME}" == "pull_request" ]; then + RELEASE_NAME="pr-$(jq --raw-output .pull_request.number "${GITHUB_EVENT_PATH}")" + RELEASE_TRANSIENT='true' + else + RELEASE_NAME="latest" + RELEASE_TRANSIENT='false' + fi + + echo "Using RELEASE_NAME=${RELEASE_NAME}" + echo "RELEASE_NAME=${RELEASE_NAME}" >> $GITHUB_ENV + + echo "Using RELEASE_TRANSIENT=${RELEASE_TRANSIENT}" + echo "RELEASE_TRANSIENT=${RELEASE_TRANSIENT}" >> $GITHUB_ENV + + DOCKER_REPOSITORY="${GITHUB_REPOSITORY,,}" + + echo "Using DOCKER_REPOSITORY=${DOCKER_REPOSITORY}" + echo "DOCKER_REPOSITORY=${DOCKER_REPOSITORY}" >> $GITHUB_ENV + + - name: Create Github Deployment + uses: bobheadxi/deployments@v0.4.3 + id: deployment + with: + step: start + token: ${{ secrets.GITHUB_TOKEN }} + env: '${{ env.RELEASE_NAME }}' + ref: '${{ github.head_ref }}' + transient: ${{ env.RELEASE_TRANSIENT }} + logs: 'https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}' + no_override: false + + - uses: actions/checkout@v2 + + - name: 'Initialize Chef Habitat environment' + uses: JarvusInnovations/habitat-action@action/v1 + with: + deps: | + jarvus/hologit + + - id: site-projection + name: 'Project holobranch: emergence-site' + uses: JarvusInnovations/hologit@actions/projector/v1 + with: + # use HEAD checked out above by checkout action + ref: HEAD + fetch: false + holobranch: emergence-site + + - id: fixtures-projection + name: 'Project holobranch: fixtures' + uses: JarvusInnovations/hologit@actions/projector/v1 + with: + # use HEAD checked out above by checkout action + ref: HEAD + fetch: false + holobranch: fixtures + + - id: helm-projection + name: 'Project holobranch: helm-chart' + uses: JarvusInnovations/hologit@actions/projector/v1 + with: + # use HEAD checked out above by checkout action + ref: HEAD + fetch: false + holobranch: helm-chart + + - name: Build & push Docker image + uses: whoan/docker-build-with-cache-action@v5 + with: + dockerfile: Dockerfile + username: ${{ github.actor }} + password: ${{ env.GITHUB_TOKEN }} + registry: ${{ env.DOCKER_REGISTRY }} + image_name: ${{ env.DOCKER_REPOSITORY }}/${{ env.DOCKER_PACKAGE }} + image_tag: ${{ env.RELEASE_NAME }} + build_extra_args: | + --build-arg=SITE_TREE=${{ steps.site-projection.outputs.tree }} + --build-arg=SITE_VERSION=0.0.0-${{ env.RELEASE_NAME }} + --build-arg=SOURCE_COMMIT=${{ github.sha }} + --build-arg=SOURCE_TAG=${{ env.RELEASE_NAME }} + --build-arg=HAB_LICENSE=${{ env.HAB_LICENSE }} + + - name: Configure kubectl + run: | + set -e + test -e ~/.kube || mkdir ~/.kube + printf '%s' "$KUBE_CONFIG_DATA" | base64 -d > ~/.kube/config + + - name: Deploy instance via Helm template + run: | + release_hostname="${RELEASE_NAME}.${KUBE_HOSTNAME}" + + echo "Ensuring current context is namespace ${KUBE_NAMESPACE}" + kubectl config set-context --current --namespace="${KUBE_NAMESPACE}" + + echo "Listing pods existing before deploy" + kubectl get pods \ + -l app.kubernetes.io/instance="${RELEASE_NAME}" \ + --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}' \ + | sort \ + | tee ./.pods-before + + echo "Extracting projected helm-chart to temporary directory" + temp_dir=$(mktemp -d) + git archive --format=tar "${{ steps.helm-projection.outputs.tree }}" | ( cd "${temp_dir}" && tar -xf - ) + + echo "Using helm upgrade to apply helm-chart to release ${RELEASE_NAME}" + helm upgrade "${RELEASE_NAME}" "${temp_dir}" \ + --install \ + --namespace "${KUBE_NAMESPACE}" \ + --set site.name="${RELEASE_NAME}" \ + --set site.title="laddr/${RELEASE_NAME}" \ + --set site.image.repository="${DOCKER_REGISTRY}/${DOCKER_REPOSITORY}/${DOCKER_PACKAGE}" \ + --set site.image.tag="${RELEASE_NAME}" \ + --set ingress.enabled=true \ + --set site.canonicalHostname="${release_hostname}" \ + --set site.displayErrors=true \ + --set hab.license=accept-no-persist + + echo "Listing pods existing after deploy" + kubectl get pods \ + -l app.kubernetes.io/instance="${RELEASE_NAME}" \ + --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}' \ + | sort \ + | tee ./.pods-after + + echo "Deleting stale pods to force image refresh" + comm -12 ./.pods-before ./.pods-after \ + | xargs --no-run-if-empty kubectl delete pod + + - name: Wait for Deployment to be ready + timeout-minutes: 10 + run: | + until kubectl rollout status deployment "${RELEASE_NAME}" 2>/dev/null >/dev/null; do + echo -n "." + sleep .5 + done + + - name: Find new Pod + run: | + POD_NAME=$( + kubectl get pod \ + -l app.kubernetes.io/instance="${RELEASE_NAME}" \ + -o jsonpath='{.items[0].metadata.name}' + ) + + echo "Using POD_NAME=${POD_NAME}" + echo "POD_NAME=${POD_NAME}" >> $GITHUB_ENV + + - name: Wait For Pod to be ready + timeout-minutes: 5 + run: kubectl wait --for condition=ready "pod/${POD_NAME}" --timeout=30s + + - name: Wait for MySQL to be Ready + timeout-minutes: 5 + run: | + until kubectl exec "${POD_NAME}" -- hab pkg exec "${HAB_ORIGIN}/${DOCKER_PACKAGE}" mysqladmin ping; do + sleep .5 + done + + - name: Load fixtures into database + run: | + echo "Dropping any existing database..." + kubectl exec "${POD_NAME}" -- \ + hab pkg exec "${HAB_ORIGIN}/${DOCKER_PACKAGE}" \ + mysqladmin drop "${DATABASE_NAME}" --force \ + || true + + echo "Creating an empty database..." + kubectl exec "${POD_NAME}" -- \ + hab pkg exec "${HAB_ORIGIN}/${DOCKER_PACKAGE}" \ + mysqladmin create "${DATABASE_NAME}" + + echo "Loading fixtures..." + ( + for fixture_file in $(git ls-tree -r --name-only ${{ steps.fixtures-projection.outputs.tree }}); do + git cat-file -p "${{ steps.fixtures-projection.outputs.tree }}:${fixture_file}" + done + ) | kubectl exec -i "${POD_NAME}" -- \ + hab pkg exec "${HAB_ORIGIN}/${DOCKER_PACKAGE}" \ + mysql "${DATABASE_NAME}" + + echo "Running migrations..." + kubectl exec "${POD_NAME}" -- \ + hab pkg exec "${HAB_ORIGIN}/${DOCKER_PACKAGE}" \ + emergence-console-run migrations:execute --all + + - name: Update Github Deployment + uses: bobheadxi/deployments@v0.4.3 + if: ${{ always() }} + with: + step: finish + token: ${{ secrets.GITHUB_TOKEN }} + status: ${{ job.status }} + deployment_id: ${{ steps.deployment.outputs.deployment_id }} + env_url: 'https://${{ env.RELEASE_NAME}}.${{ env.KUBE_HOSTNAME }}/' + logs: 'https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}' diff --git a/.github/workflows/k8s-destroy.yml b/.github/workflows/k8s-destroy.yml new file mode 100644 index 00000000..a3d879c7 --- /dev/null +++ b/.github/workflows/k8s-destroy.yml @@ -0,0 +1,38 @@ +name: Destroy K8s Preview + +on: + pull_request: + branches: [ develop ] + types: [ closed ] + +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + KUBE_CONFIG_DATA: ${{ secrets.KUBECONFIG_BASE64 }} + KUBE_NAMESPACE: codeforphilly + + RELEASE_NAME: pr-${{ github.event.number }} + +jobs: + + k8s-destroy: + runs-on: ubuntu-latest + steps: + + - name: Configure kubectl + run: | + test -e ~/.kube || mkdir ~/.kube + printf '%s' "$KUBE_CONFIG_DATA" | base64 -d > ~/.kube/config + + - name: Delete PR Deployment + run: | + kubectl config set-context --current --namespace="${KUBE_NAMESPACE}" + kubectl delete deployment,replicaset,ingress,all -l "app.kubernetes.io/instance=${RELEASE_NAME}" + kubectl delete secret "${RELEASE_NAME}-tls" + + - name: Deactivate Github Deployment + uses: bobheadxi/deployments@v0.4.3 + with: + step: deactivate-env + token: ${{ secrets.GITHUB_TOKEN }} + env: '${{ env.RELEASE_NAME }}' From f69e9533baa3ce9d60c0dbfc079a256ee7b32811 Mon Sep 17 00:00:00 2001 From: Chris Alfano Date: Thu, 26 Aug 2021 18:29:01 +0000 Subject: [PATCH 3/7] fix(ci): deploy to namespace code-for-philly --- .github/workflows/k8s-deploy.yml | 2 +- .github/workflows/k8s-destroy.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/k8s-deploy.yml b/.github/workflows/k8s-deploy.yml index 67ae0089..f8b181ec 100644 --- a/.github/workflows/k8s-deploy.yml +++ b/.github/workflows/k8s-deploy.yml @@ -14,7 +14,7 @@ env: DOCKER_PACKAGE: codeforphilly-composite KUBE_CONFIG_DATA: ${{ secrets.KUBECONFIG_BASE64 }} - KUBE_NAMESPACE: codeforphilly + KUBE_NAMESPACE: code-for-philly KUBE_HOSTNAME: codeforphilly.sandbox.k8s.phl.io DATABASE_NAME: codeforphilly diff --git a/.github/workflows/k8s-destroy.yml b/.github/workflows/k8s-destroy.yml index a3d879c7..1093338e 100644 --- a/.github/workflows/k8s-destroy.yml +++ b/.github/workflows/k8s-destroy.yml @@ -9,7 +9,7 @@ env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} KUBE_CONFIG_DATA: ${{ secrets.KUBECONFIG_BASE64 }} - KUBE_NAMESPACE: codeforphilly + KUBE_NAMESPACE: code-for-philly RELEASE_NAME: pr-${{ github.event.number }} From c1f782b36d654a4a923c87af1bf0f5512e9e2e14 Mon Sep 17 00:00:00 2001 From: Chris Alfano Date: Thu, 26 Aug 2021 19:04:26 +0000 Subject: [PATCH 4/7] fix(k8s): use generic/default pkg name site --- Dockerfile | 8 ++++---- habitat/plan.sh | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index cbe9c74b..c98b8f7c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -54,13 +54,13 @@ RUN hab pkg exec core/hab-plan-build hab-plan-build /src/habitat/composite FROM habitat as runtime # configure persistent volumes -RUN hab pkg exec core/coreutils mkdir -p '/hab/svc/mysql/data' '/hab/svc/codeforphilly/data' '/hab/svc/nginx/files' \ - && hab pkg exec core/coreutils chown hab:hab -R '/hab/svc/mysql/data' '/hab/svc/codeforphilly/data' '/hab/svc/nginx/files' +RUN hab pkg exec core/coreutils mkdir -p '/hab/svc/mysql/data' '/hab/svc/site/data' '/hab/svc/nginx/files' \ + && hab pkg exec core/coreutils chown hab:hab -R '/hab/svc/mysql/data' '/hab/svc/site/data' '/hab/svc/nginx/files' # configure entrypoint -VOLUME ["/hab/svc/mysql/data", "/hab/svc/codeforphilly/data", "/hab/svc/nginx/files"] +VOLUME ["/hab/svc/mysql/data", "/hab/svc/site/data", "/hab/svc/nginx/files"] ENTRYPOINT ["hab", "sup", "run"] -CMD ["codeforphilly/codeforphilly-composite"] +CMD ["codeforphilly/site-composite"] # install .hart artifact from builder stage COPY --from=projector /hab/cache/artifacts/$HAB_ORIGIN-* /hab/cache/artifacts/ diff --git a/habitat/plan.sh b/habitat/plan.sh index a329f724..8beddd65 100644 --- a/habitat/plan.sh +++ b/habitat/plan.sh @@ -1,4 +1,4 @@ -pkg_name=codeforphilly +pkg_name=site pkg_origin=codeforphilly pkg_maintainer="Code for Philly " pkg_scaffolding=emergence/scaffolding-site From f4c21e0c78c34389f2093e41748b109e31625c32 Mon Sep 17 00:00:00 2001 From: Chris Alfano Date: Thu, 26 Aug 2021 19:17:45 +0000 Subject: [PATCH 5/7] fix(k8s): move lingering pkg name ref to site --- habitat/composite/plan.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/habitat/composite/plan.sh b/habitat/composite/plan.sh index 00b36161..c7ed7f9d 100644 --- a/habitat/composite/plan.sh +++ b/habitat/composite/plan.sh @@ -1,4 +1,4 @@ -composite_app_pkg_name=codeforphilly +composite_app_pkg_name=site pkg_name="${composite_app_pkg_name}-composite" pkg_origin=codeforphilly pkg_maintainer="Code for Philly " From 185952aadf159a7a2d560add97ff5589c5f920f3 Mon Sep 17 00:00:00 2001 From: Chris Alfano Date: Thu, 26 Aug 2021 19:26:46 +0000 Subject: [PATCH 6/7] fix(ci): update package name in k8s deploy workflow --- .github/workflows/k8s-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/k8s-deploy.yml b/.github/workflows/k8s-deploy.yml index f8b181ec..7a3e557f 100644 --- a/.github/workflows/k8s-deploy.yml +++ b/.github/workflows/k8s-deploy.yml @@ -11,7 +11,7 @@ env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} DOCKER_REGISTRY: ghcr.io - DOCKER_PACKAGE: codeforphilly-composite + DOCKER_PACKAGE: site-composite KUBE_CONFIG_DATA: ${{ secrets.KUBECONFIG_BASE64 }} KUBE_NAMESPACE: code-for-philly From 56298f992c9ab50b3d59481b319e672a3aef6a80 Mon Sep 17 00:00:00 2001 From: Chris Alfano Date: Thu, 26 Aug 2021 21:02:34 +0000 Subject: [PATCH 7/7] chore(deps): bump laddr to v3.0.5 --- .holo/sources/laddr.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.holo/sources/laddr.toml b/.holo/sources/laddr.toml index bad06192..da1e17d9 100644 --- a/.holo/sources/laddr.toml +++ b/.holo/sources/laddr.toml @@ -1,3 +1,3 @@ [holosource] url = "https://github.com/CodeForPhilly/laddr" -ref = "refs/tags/v3.0.4" +ref = "refs/tags/v3.0.5"