Skip to content

Commit

Permalink
test build_and_deploy_hold workflow (#1661)
Browse files Browse the repository at this point in the history
this pr add a build and deploy workflow with hold state. 

- Requires an environment `production` set in repo's settings with a 'require reviewers' protection rule on for team slapshot as qualify members to approve before workflow start deployment.
- `deploy_hold.yml` is made to use the environment `production` setting. The github action `build_and_deploy_hold`, after receiving approval, will deploy three set of assets in folders with name based on tag version, major version and minor version. (/v1.2.3, /v1.2, /v1)
  - For tag release for support branches, such as cases where v1.2.1 is release but there's a newer version v1.3.0 previously release, we don't want to deploy to v1 (major version) and only to v1.2 (minor version) and v1.2.1 (tag version). Added `should_deploy_major_version` job to ensure this behavior

Note: There are some limitations in how secrets and environments can work with reusable workflows (discussions in this [github post](https://github.community/t/reusable-workflows-secrets-and-environments/203695)). There's also a [repo](https://github.com/AllanOricil/workflow-template-bug/blob/master/.github/workflows/workflow-inplementation.yml) with some examples to show issues with environment and secrets when use certain ways.

To summarize:
I can't set `environment` in the top level job and use `uses` to call `deploy` workflow. That's not supported and seems to [error out during testing](https://github.com/yext/answers-search-ui/actions/runs/1763550565/workflow): `workflow is not valid, unexpected value 'uses'`. This mean `environment` have to either:
1) get pass into the reusable workflow `deploy.yml` as an input (similar to my-workflow-job-4 in the example repo):
   - this requires a default `staging` environment without approval restriction and this would spam prs with messages of deploying to staging (as shown in this pr), which could get annoying and cluttering up prs. But if the team is alright with this, I can update to use this approach.
2) hardcode into the workflow (similar to my-workflow-job-3 in the example repo):
   - this is what I have in `deploy_hold.yml` workflow where environment is hardcoded to `production`. Supposedly, when trying to access secrets in an action with an environment specified, github would check for the environment secrets first before checking repo secrets automatically so we don't have to pass in the secrets. But that [didn't work during testing](850e86e) so I kept the secrets as inputs.

I also can't combine all the deploy jobs into one with 'steps' field because `secrets` input field for workflows in `steps` field is not supported. But I think it make sense for them to be separate jobs anyway since they are not dependent on each other, even though it feels a little like duplicating code.

J=SLAP-1818
TEST=manual

push a tag to repo, and see build_and_deploy_hold workflow ran: https://github.com/yext/answers-search-ui/actions/runs/1763784557. Check in s3 buckets from this branch's dir and see the expected assets in folders with major/minor/full versions in there.
push two tags: test-v3.4.0 and test-v3.3.0 in order. See that the first tag deploy all versions and the second tag cancel the major version deployment ([test](https://github.com/yext/answers-search-ui/actions/runs/1774931889))
  • Loading branch information
yen-tt committed Jan 31, 2022
1 parent 8cc2b42 commit 5dd6206
Show file tree
Hide file tree
Showing 3 changed files with 216 additions and 55 deletions.
110 changes: 55 additions & 55 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -294,61 +294,61 @@ workflows:
# - headless_acceptance_test
# - browserstack_acceptance_test
# - useragent_acceptance_test
build_and_deploy_hold:
jobs:
- build_i18n:
filters:
tags:
only: /^v.*/
branches:
ignore: /.*/
- unit_test:
filters:
tags:
only: /^v.*/
requires:
- build_i18n
- headless_acceptance_test:
filters:
tags:
only: /^v.*/
requires:
- build_i18n
- browserstack_acceptance_test:
filters:
tags:
only: /^v.*/
requires:
- build_i18n
- useragent_acceptance_test:
filters:
tags:
only: /^v.*/
requires:
- build_i18n
- translation_test:
filters:
tags:
only: /^v.*/
requires:
- build_i18n
- hold:
type: approval
filters:
tags:
only: /^v.*/
requires:
- unit_test
- browserstack_acceptance_test
- useragent_acceptance_test
- headless_acceptance_test
- translation_test
- deploy_version:
filters:
tags:
only: /^v.*/
requires:
- hold
# build_and_deploy_hold:
# jobs:
# - build_i18n:
# filters:
# tags:
# only: /^v.*/
# branches:
# ignore: /.*/
# - unit_test:
# filters:
# tags:
# only: /^v.*/
# requires:
# - build_i18n
# - headless_acceptance_test:
# filters:
# tags:
# only: /^v.*/
# requires:
# - build_i18n
# - browserstack_acceptance_test:
# filters:
# tags:
# only: /^v.*/
# requires:
# - build_i18n
# - useragent_acceptance_test:
# filters:
# tags:
# only: /^v.*/
# requires:
# - build_i18n
# - translation_test:
# filters:
# tags:
# only: /^v.*/
# requires:
# - build_i18n
# - hold:
# type: approval
# filters:
# tags:
# only: /^v.*/
# requires:
# - unit_test
# - browserstack_acceptance_test
# - useragent_acceptance_test
# - headless_acceptance_test
# - translation_test
# - deploy_version:
# filters:
# tags:
# only: /^v.*/
# requires:
# - hold
build_and_deploy_search_bar:
jobs:
- build_search_bar:
Expand Down
116 changes: 116 additions & 0 deletions .github/workflows/build_and_deploy_hold.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
name: Build and deploy with a hold state

on:
push:
tags:
- 'v*'

jobs:
call_build:
uses: ./.github/workflows/build.yml
with:
build_script: build-locales

call_unit_test:
uses: ./.github/workflows/unit_test.yml
needs: call_build

call_misc_tests:
uses: ./.github/workflows/miscellaneous_tests.yml

call_acceptance:
uses: ./.github/workflows/acceptance.yml
needs: call_build
secrets:
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}

call_format_branch_name:
uses: ./.github/workflows/format_branch_name.yml

extract_versions:
runs-on: ubuntu-latest
outputs:
minor_version: ${{ steps.vars.outputs.minor_version }}
major_version: ${{ steps.vars.outputs.major_version }}
steps:
- name: extract major and minor substrings
id: vars
run: |
MINOR_VERSION="$(echo "${{ github.ref_name }}" | cut -d '.' -f 1,2)"
echo $MINOR_VERSION
echo ::set-output name=minor_version::${MINOR_VERSION}
MAJOR_VERSION="$(echo "${{ github.ref_name }}" | cut -d '.' -f 1)"
echo $MAJOR_VERSION
echo ::set-output name=major_version::${MAJOR_VERSION}
should_deploy_major_version:
runs-on: ubuntu-latest
outputs:
deploy_major_version: ${{ steps.vars.outputs.deploy_major_version }}
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: allow for major version deployment if the next minor version from current tag does not exist
id: vars
run: |
MINOR_VERSION=$(echo "${{ github.ref_name }}" | cut -d '.' -f 2)
MAJOR_VERSION=$(echo "${{ github.ref_name }}" | cut -d '.' -f 1)
NEXT_MINOR_VERSION=$(( $MINOR_VERSION + 1 ))
OUTPUT=$(git tag --list "$MAJOR_VERSION.$NEXT_MINOR_VERSION.*")
if [ -z $OUTPUT ]
then
echo ::set-output name=deploy_major_version::true
fi
call_deploy_tag_version:
needs:
- call_unit_test
- call_format_branch_name
- call_acceptance
- extract_versions
- call_misc_tests
uses: ./.github/workflows/deploy_hold.yml
with:
directory: ${{ github.ref_name }}
cache-control: 'max-age=31536000'
secrets:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

call_deploy_major_version:
needs:
- call_unit_test
- call_format_branch_name
- call_acceptance
- extract_versions
- call_misc_tests
- should_deploy_major_version
if: ${{ needs.should_deploy_major_version.outputs.deploy_major_version }}
uses: ./.github/workflows/deploy_hold.yml
with:
directory: ${{ needs.extract_versions.outputs.major_version }}
cache-control: 'max-age=43200'
secrets:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

call_deploy_minor_version:
needs:
- call_unit_test
- call_format_branch_name
- call_acceptance
- extract_versions
- call_misc_tests
uses: ./.github/workflows/deploy_hold.yml
with:
directory: ${{ needs.extract_versions.outputs.minor_version }}
cache-control: 'max-age=43200'
secrets:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

concurrency:
group: ci-build-and-deploy-hold-${{ github.ref }}-1
cancel-in-progress: true
45 changes: 45 additions & 0 deletions .github/workflows/deploy_hold.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Deploy assets to AWS S3 with hold state setup in github's production environment

on:
workflow_call:
inputs:
bucket:
required: false
type: string
default: answers
directory:
required: true
type: string
cache-control:
required: false
type: string
default: no-cache
secrets:
AWS_ACCESS_KEY_ID:
required: true
AWS_SECRET_ACCESS_KEY:
required: true

jobs:
deploy:
runs-on: ubuntu-latest
environment: production # sets in github repo with reiewer requirement protection rule
steps:
- uses: actions/checkout@v2
- name: Download build-output artifact
uses: actions/download-artifact@v2
with:
name: build-output
path: dist/
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Deploy to S3
run: |
aws s3 cp ./dist/ s3://assets.sitescdn.net/${{ inputs.bucket }}/${{ inputs.directory }} \
--acl public-read \
--recursive \
--cache-control ${{ inputs.cache-control }}

0 comments on commit 5dd6206

Please sign in to comment.