Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: scheduled deploy #203

Merged
merged 12 commits into from
Oct 8, 2024
4 changes: 2 additions & 2 deletions .github/workflows/code_quality.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ jobs:
- name: Checkout
uses: actions/checkout@v2

- name: Use Node.js 16.13
- name: Use Node.js 16.14
uses: actions/setup-node@v2
with:
node-version: 16.13
node-version: 16.14
cache: 'npm'

- name: Install dependencies
Expand Down
103 changes: 4 additions & 99 deletions .github/workflows/docker-publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,102 +16,7 @@ jobs:
build-and-push:
if: ${{ github.event.workflow_run.conclusion == 'success' || github.event.action == 'published' }}
name: Build and Push
environment: ${{ startsWith(github.ref, 'refs/tags/') && 'prod' || 'dev' }}
runs-on: ubuntu-latest
outputs:
version: ${{ steps.get-version.outputs.version }}
commit: ${{ steps.get-commit-id.outputs.commit }}
environment: ${{ steps.set-environment.outputs.environment }}
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ vars.AWS_REGION }}

- name: Configure Node
uses: actions/setup-node@v4
with:
node-version: 16.13
registry-url: 'https://npm.pkg.github.com'
scope: '@zeplin'
cache: 'npm'

- id: get-commit-id
name: Get commit id
run: echo "commit=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT

- name: Create revision file
run: echo $(date +%s)-${{ steps.get-commit-id.outputs.commit }} >./revision.txt

- id: get-version
name: Get version
run: echo "version=${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || '' }}" >> $GITHUB_OUTPUT

- name: Set package version
if: ${{ steps.get-version.outputs.version }} # ${GITHUB_REF} does not have a tag if this is not set above
run: npm version ${GITHUB_REF#refs/tags/v} --no-git-tag-version --allow-same-version

- id: set-environment
name: Set environment
run: echo "environment=${{ startsWith(github.ref, 'refs/tags/') && 'prod' || 'dev' }}" >> $GITHUB_OUTPUT

- name: Install all dependencies
run: npm ci --ignore-scripts
env:
NODE_AUTH_TOKEN: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }}

- name: Run post install scripts of dependencies
run: npm rebuild && npm run prepare --if-present

- name: Build
run: npm run build
env:
NEXT_PUBLIC_SENTRY_DSN: ${{ secrets.NEXT_PUBLIC_SENTRY_DSN_PROD }}
NEXT_PUBLIC_IS_SENTRY_ENABLED: ${{ secrets.NEXT_PUBLIC_IS_SENTRY_ENABLED_PROD }}
NEXT_PUBLIC_ZEPLIN_WEB_APP_BASE_URL: ${{ secrets.NEXT_PUBLIC_ZEPLIN_WEB_APP_BASE_URL_PROD }}
NEXT_PUBLIC_ZEPLIN_APP_URI_SCHEME: ${{ secrets.NEXT_PUBLIC_ZEPLIN_APP_URI_SCHEME_PROD }}
NEXT_PUBLIC_ENVIRONMENT: ${{ inputs.environment }}

- name: Install dependencies without devDependencies
run: npm ci --omit=dev --ignore-scripts
env:
NODE_AUTH_TOKEN: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }}

- name: Run post install scripts of dependencies
run: npm rebuild && npm run prepare --if-present

- name: Build and push Docker image to AWS ECR
run: |
REPO="${{ vars.AWS_ACCOUNT_ID || '915497967985' }}.dkr.ecr.${{ vars.AWS_REGION }}.amazonaws.com"
IMAGE="$REPO/microsoft-teams-app:${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || steps.get-commit-id.outputs.commit }}"
IMAGE_WITH_ENV_TAG="$REPO/microsoft-teams-app:${{ steps.set-environment.outputs.environment }}"
docker build -t $IMAGE .
docker tag $IMAGE $IMAGE_WITH_ENV_TAG
aws ecr get-login-password --region ${{ vars.AWS_REGION }} | docker login --username AWS --password-stdin $REPO
docker push $IMAGE
docker push $IMAGE_WITH_ENV_TAG

- name: Trigger infra workflow to deploy new image version
run: |
JSON_DATA=$(
jq -n -c \
--arg a "${{ env.APP_NAME }}" \
--arg b "${{ github.ref_name }}" \
--arg t "${{ github.ref_name }}" \
--arg v "${{ steps.get-version.outputs.version }}" \
--arg c "${{ steps.get-commit-id.outputs.commit }}" \
--arg e "${{ steps.set-environment.outputs.environment }}" \
--arg n "${{ vars.NEWRELIC_APPLICATION_GUID }}" \
--arg s "${{ env.APP_NAME }}" \
'{"app-name": $a, "branch": $b, "version": $v, "tag": $t, "commit-id": $c, "environment": $e, "newrelic-guid": $n, "sentry-project": $s }'
)
echo $JSON_DATA | gh workflow run deploy-app.yaml --repo zeplin/infra --json
echo "Workflow is triggered: https://github.com/zeplin/infra/actions/workflows/deploy-app.yaml"
env:
GH_TOKEN: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }}
APP_NAME: microsoft-teams-app
uses: ./.github/workflows/reusable-docker-publish.yaml
with:
environment: ${{ startsWith(github.ref, 'refs/tags/') && 'prod' || 'dev' }}
secrets: inherit
126 changes: 126 additions & 0 deletions .github/workflows/reusable-docker-publish.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
name: reusable / Docker Publish

on:
workflow_call:
inputs:
environment:
required: true
type: string
ref:
required: false
type: string

jobs:
build-and-push:
name: Build and Push
environment: ${{ inputs.environment }}
runs-on: ubuntu-latest
env:
APP_NAME: microsoft-teams-app
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ inputs.ref }}

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ vars.AWS_REGION }}

- name: Configure Node
uses: actions/setup-node@v4
with:
node-version: 16.14
registry-url: 'https://npm.pkg.github.com'
scope: '@zeplin'
cache: 'npm'

- id: get-commit-id
name: Get commit id
if: ${{ github.event_name != 'schedule' || inputs.environment == 'dev' }}
run: echo "commit-id=${GITHUB_SHA::7}" >> $GITHUB_ENV

- id: get-latest-sha
name: Get commit SHA of latest tag for prod (scheduled flow)
if: ${{ inputs.environment == 'prod' && github.event_name == 'schedule' }}
# use inputs.ref to get the commit id
run: |
LATEST_SHA=$(git rev-list -n 1 "${{ inputs.ref }}")
echo "commit-id=${LATEST_SHA::7}" >> $GITHUB_ENV

- name: Create revision file
run: echo $(date +%s)-${{ env.commit-id }} > ./revision.txt

- id: get-version
name: Get version
run: |
if [ "${{ github.event_name }}" == "schedule" ]; then
echo "version=${{ inputs.ref }}" >> $GITHUB_ENV
else
echo "version=${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || '' }}" >> $GITHUB_ENV
fi

- name: Set package version
if: ${{ env.version }}
run: |
version=${{ env.version }}
version=${version#v}
npm version $version --no-git-tag-version --allow-same-version

- name: Install all dependencies
run: npm ci --ignore-scripts
env:
NODE_AUTH_TOKEN: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }}

- name: Run post install scripts of dependencies
run: npm rebuild && npm run prepare --if-present

- name: Build
run: npm run build
env:
NEXT_PUBLIC_SENTRY_DSN: ${{ secrets.NEXT_PUBLIC_SENTRY_DSN_PROD }}
NEXT_PUBLIC_IS_SENTRY_ENABLED: ${{ secrets.NEXT_PUBLIC_IS_SENTRY_ENABLED_PROD }}
NEXT_PUBLIC_ZEPLIN_WEB_APP_BASE_URL: ${{ secrets.NEXT_PUBLIC_ZEPLIN_WEB_APP_BASE_URL_PROD }}
NEXT_PUBLIC_ZEPLIN_APP_URI_SCHEME: ${{ secrets.NEXT_PUBLIC_ZEPLIN_APP_URI_SCHEME_PROD }}
NEXT_PUBLIC_ENVIRONMENT: ${{ inputs.environment }}

- name: Install dependencies without devDependencies
run: npm ci --omit=dev --ignore-scripts
env:
NODE_AUTH_TOKEN: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }}

- name: Run post install scripts of dependencies
run: npm rebuild && npm run prepare --if-present

- name: Build and push Docker image to AWS ECR
run: |
REPO="${{ vars.AWS_ACCOUNT_ID }}.dkr.ecr.${{ vars.AWS_REGION }}.amazonaws.com"
IMAGE="$REPO/$APP_NAME:${{ env.version || env.commit-id }}"
IMAGE_WITH_ENV_TAG="$REPO/$APP_NAME:${{ inputs.environment }}"
docker build -t $IMAGE .
docker tag $IMAGE $IMAGE_WITH_ENV_TAG
aws ecr get-login-password --region ${{ vars.AWS_REGION }} | docker login --username AWS --password-stdin $REPO
docker push $IMAGE
docker push $IMAGE_WITH_ENV_TAG

- name: Trigger infra workflow to deploy new image version
run: |
JSON_DATA=$(
jq -n -c \
--arg a "$APP_NAME" \
--arg b "${{ env.version || github.ref_name }}" \
--arg t "${{ env.version || github.ref_name }}" \
--arg v "${{ env.version }}" \
--arg c "${{ env.commit-id }}" \
--arg e "${{ inputs.environment }}" \
--arg n "${{ vars.NEWRELIC_APPLICATION_GUID }}" \
--arg s "$APP_NAME" \
'{"app-name": $a, "branch": $b, "version": $v, "tag": $t, "commit-id": $c, "environment": $e, "newrelic-guid": $n, "sentry-project": $s }'
)
echo $JSON_DATA | gh workflow run deploy-app.yaml --repo zeplin/infra --json
echo "Workflow is triggered: https://github.com/zeplin/infra/actions/workflows/deploy-app.yaml"
env:
GH_TOKEN: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }}
47 changes: 47 additions & 0 deletions .github/workflows/scheduled-docker-publish-prod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
on:
schedule:
- cron: '0 5 * * 3' # at 05:00 UTC every Wednesday

name: Scheduled - Build and Push to ECR (prod)

jobs:
# The workflow should work only in the first week of the month
check-first-week:
runs-on: ubuntu-latest
outputs:
is-first-week-of-month: ${{ steps.check-week.outputs.is-first-week }}
steps:
- name: Check if it's the first week of the month
id: check-week
run: |
if [ $(date +'%d' | sed 's/^0*//') -le 7 ]; then
echo "is-first-week=true" >> $GITHUB_OUTPUT
else
echo "is-first-week=false" >> $GITHUB_OUTPUT
fi
get-latest-tag:
needs: check-first-week
if: ${{ needs.check-first-week.outputs.is-first-week-of-month == 'true' }}
name: "Get latest tag"
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
# Required due to the way Git works, without it this action won't be able to find any or the correct tags
fetch-depth: 0
- name: Get latest tag
id: get-latest-tag
uses: "WyriHaximus/github-action-get-previous-tag@v1"
with:
prefix: v
outputs:
latest-tag: ${{ steps.get-latest-tag.outputs.tag }}
build-and-push:
needs: get-latest-tag
name: (prod) Scheduled Build and Push
uses: ./.github/workflows/reusable-docker-publish.yaml
with:
environment: "prod"
ref: ${{ needs.get-latest-tag.outputs.latest-tag }}
secrets: inherit
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v16.13.0
v16.14
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:16.13.0
FROM node:16.14-slim
RUN apt-get update && apt-get install tini
RUN npm install pm2 -g

Expand Down
Loading