Test, build and push Docker Image #171
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Test, build and push Docker Image | |
on: | |
# This workflow will run everyday at 7:00AM, 10:00AM, 1:00PM, 4:00PM IST on weekdays | |
schedule: | |
- cron: "30 1-12/3 * * 1-5" | |
# This line enables manual triggering of this workflow. | |
workflow_dispatch: | |
inputs: | |
tags: | |
description: "Tags" | |
required: false | |
type: string | |
default: "" | |
# trigger for pushes to master | |
push: | |
branches: [master] | |
paths: | |
- "app/client/**" | |
- "app/server/**" | |
- "app/client/packages/rts/**" | |
- "!app/client/cypress/manual_TestSuite/**" | |
jobs: | |
setup: | |
runs-on: ubuntu-latest | |
outputs: | |
tags: ${{ steps.setup.outputs.tags }} | |
matrix: ${{ steps.setup.outputs.matrix }} | |
steps: | |
- name: Set tags and matrix runner | |
id: setup | |
run: | | |
if [ "${{github.event_name}}" == "workflow_dispatch" ]; then | |
if [[ "${{inputs.tags}}" != "" && "${{inputs.tags}}" != *"@tag.All"* ]]; then | |
echo "tags=${{inputs.tags}}" >> $GITHUB_OUTPUT | |
echo "matrix=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]" >> $GITHUB_OUTPUT | |
else | |
echo "tags=" >> $GITHUB_OUTPUT | |
echo "matrix=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59]" >> $GITHUB_OUTPUT | |
fi | |
else | |
echo "tags=" >> $GITHUB_OUTPUT | |
echo "matrix=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59]" >> $GITHUB_OUTPUT | |
fi | |
server-build: | |
needs: [setup] | |
if: success() | |
name: server-build | |
uses: ./.github/workflows/server-build.yml | |
secrets: inherit | |
with: | |
pr: 0 | |
skip-tests: true | |
client-build: | |
needs: [setup] | |
if: success() | |
name: client-build | |
uses: ./.github/workflows/client-build.yml | |
secrets: inherit | |
with: | |
pr: 0 | |
rts-build: | |
needs: [setup] | |
if: success() | |
name: rts-build | |
uses: ./.github/workflows/rts-build.yml | |
secrets: inherit | |
with: | |
pr: 0 | |
build-docker-image: | |
needs: [client-build, server-build, rts-build] | |
# Only run if the build step is successful | |
if: success() | |
name: build-docker-image | |
uses: ./.github/workflows/build-docker-image.yml | |
secrets: inherit | |
with: | |
pr: 0 | |
ci-test: | |
needs: [setup, build-docker-image] | |
# Only run if the build step is successful | |
if: success() && ( github.event_name != 'push' || github.ref == 'refs/heads/master' ) | |
name: ci-test | |
uses: ./.github/workflows/ci-test-custom-script.yml | |
secrets: inherit | |
with: | |
pr: 0 | |
tags: ${{needs.setup.outputs.tags}} | |
matrix: ${{needs.setup.outputs.matrix}} | |
server-unit-tests: | |
name: server-unit-tests | |
needs: [build-docker-image] | |
if: success() && ( github.event_name != 'push' || github.ref == 'refs/heads/master' ) | |
uses: ./.github/workflows/server-build.yml | |
secrets: inherit | |
with: | |
pr: 0 | |
skip-tests: false | |
client-unit-tests: | |
name: client-unit-tests | |
needs: [build-docker-image] | |
if: success() && ( github.event_name != 'push' || github.ref == 'refs/heads/master' ) | |
uses: ./.github/workflows/client-unit-tests.yml | |
secrets: inherit | |
with: | |
pr: 0 | |
ci-test-result: | |
needs: [ci-test, client-unit-tests, server-unit-tests] | |
if: always() && | |
(github.event_name == 'workflow_dispatch' || | |
github.event_name == 'schedule' || | |
( github.event_name != 'push' || github.ref == 'refs/heads/master' ) || | |
(github.event_name == 'pull_request_review' && | |
github.event.review.state == 'approved' && | |
github.event.pull_request.head.repo.full_name == github.repository)) | |
runs-on: ubuntu-latest | |
defaults: | |
run: | |
shell: bash | |
steps: | |
- run: echo "All ci-test matrices completed" | |
# Deleting the existing dir's if any | |
- name: Delete existing directories | |
if: needs.ci-test.result != 'success' | |
run: | | |
rm -f ~/failed_spec_ci | |
rm -f ~/combined_failed_spec_ci | |
# Download failed_spec_ci list for all CI container jobs | |
- uses: actions/download-artifact@v3 | |
if: needs.ci-test.result != 'success' | |
id: download_ci | |
with: | |
name: failed-spec-ci-${{github.run_attempt}} | |
path: ~/failed_spec_ci | |
# In case for any ci job failure, create combined failed spec | |
- name: "combine all specs for CI" | |
if: needs.ci-test.result != 'success' | |
run: | | |
rm -f ~/combined_failed_spec_ci | |
cat ~/failed_spec_ci/failed_spec_ci* >> ~/combined_failed_spec_ci | |
- name: CI test failures | |
if: needs.ci-test.result != 'success' | |
shell: bash | |
run: | | |
new_failed_spec_env="<ol>$(sort -u ~/combined_failed_spec_ci | sed 's/|cypress|cypress/<\/li>\n<li>/g' | sed -e 's/^<li>//' -e 's/<\/li>$//' -e 's/<\/li>/<\/li>\n/')</ol>" | |
echo "$new_failed_spec_env" | |
echo "new_failed_spec_env<<EOF" >> $GITHUB_ENV | |
echo "$new_failed_spec_env" >> $GITHUB_ENV | |
echo "EOF" >> $GITHUB_ENV | |
- name: Generate slack message | |
continue-on-error: true | |
if: always() | |
id: slack_notification | |
env: | |
EVENT_COMMITS: ${{ toJson(github.event.commits[0].message) }} | |
run: | | |
eventCommit=$(echo ${{env.EVENT_COMMITS}} | sed "s/'//g") | |
echo "slack_username=$(echo "$eventCommit" | awk -F '\\\\n' '{print $1}' | sed 's/^"//;s/"$//')" >> $GITHUB_OUTPUT | |
if [[ ${{ needs.ci-test.result }} == 'failure' ]]; then | |
echo "slack_message=There are test failures in the run. Cypress Dashboard: <https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=${{ github.run_id }}&attempt=${{ github.run_attempt }}&selectiontype=test&testsstatus=failed&specsstatus=fail|Click here!>" >> $GITHUB_OUTPUT | |
echo "slack_color=#FF0000" >> $GITHUB_OUTPUT | |
echo "slack_icon=:no_entry:" >> $GITHUB_OUTPUT | |
elif [[ ${{ needs.ci-test.result }} == 'success' ]]; then | |
echo "slack_message=All tests passed successfully :tada: Cypress Dashboard: <https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=${{ github.run_id }}&attempt=${{ github.run_attempt }}|Click here!>" >> $GITHUB_OUTPUT | |
echo "slack_color=#00FF00" >> $GITHUB_OUTPUT | |
echo "slack_icon=:white_check_mark:" >> $GITHUB_OUTPUT | |
else | |
echo "slack_message=There are build failures. To analyze run go <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|here>" >> $GITHUB_OUTPUT | |
echo "slack_color=#FF0000" >> $GITHUB_OUTPUT | |
echo "slack_icon=:warning:" >> $GITHUB_OUTPUT | |
fi | |
- name: Slack Notification | |
continue-on-error: true | |
if: always() | |
uses: rtCamp/action-slack-notify@v2 | |
env: | |
SLACK_CHANNEL: cypresspushworkflow | |
SLACK_COLOR: ${{steps.slack_notification.outputs.slack_color}} | |
SLACK_ICON_EMOJI: ${{steps.slack_notification.outputs.slack_icon}} | |
SLACK_ICON: https://app.slack.com/services/B05D17E4QVB | |
SLACK_TITLE: "Result:" | |
SLACK_USERNAME: ${{steps.slack_notification.outputs.slack_username}} | |
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_HOSTED }} | |
MSG_MINIMAL: Ref,Event,Commit | |
SLACK_FOOTER: "Push Workflow" | |
SLACK_MESSAGE: ${{steps.slack_notification.outputs.slack_message}} | |
# Force save the CI failed spec list into a cache | |
- name: Store the combined run result for CI | |
if: needs.ci-test.result != 'success' | |
uses: martijnhols/actions-cache/save@v3 | |
with: | |
path: | | |
~/combined_failed_spec_ci | |
key: ${{ github.run_id }}-"ci-test-result" | |
restore-keys: | | |
${{ github.run_id }}-${{ github.job }} | |
# Upload combined failed CI spec list to a file | |
# This is done for debugging. | |
- name: upload combined failed spec | |
if: needs.ci-test.result != 'success' | |
uses: actions/upload-artifact@v3 | |
with: | |
name: combined_failed_spec_ci | |
path: ~/combined_failed_spec_ci | |
- name: Return status for ui-matrix | |
run: | | |
if [[ "${{ needs.ci-test.result }}" == "success" ]]; then | |
echo "Integration tests completed successfully!"; | |
exit 0; | |
elif [[ "${{ needs.ci-test.result }}" == "skipped" ]]; then | |
echo "Integration tests were skipped"; | |
exit 1; | |
else | |
echo "Integration tests have failed"; | |
exit 1; | |
fi | |
package-release: | |
needs: build-docker-image | |
runs-on: ubuntu-latest | |
# Set permissions since we're using OIDC token authentication between Depot and GitHub | |
permissions: | |
contents: read | |
id-token: write | |
# Run this job as soon as the docker image is ready, if this is the release branch | |
if: ( always() && github.ref == 'refs/heads/release' ) | |
steps: | |
- name: Checkout the head commit of the branch | |
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' | |
uses: actions/checkout@v4 | |
- name: Download the react build artifact | |
uses: actions/download-artifact@v3 | |
with: | |
name: client-build | |
path: app/client | |
- name: Unpack the client build artifact | |
if: steps.run_result.outputs.run_result != 'success' | |
run: | | |
mkdir -p app/client/build | |
tar -xvf app/client/build.tar -C app/client/build | |
- name: Download the server build artifact | |
uses: actions/download-artifact@v3 | |
with: | |
name: server-build | |
path: app/server/dist | |
- name: Download the rts build artifact | |
uses: actions/download-artifact@v3 | |
with: | |
name: rts-dist | |
path: app/client/packages/rts/dist | |
- name: Untar the rts folder | |
run: | | |
tar -xvf app/client/packages/rts/dist/rts-dist.tar -C app/client/packages/rts/ | |
echo "Cleaning up the tar files" | |
rm app/client/packages/rts/dist/rts-dist.tar | |
- name: Generate info.json | |
run: | | |
if [[ -f scripts/generate_info_json.sh ]]; then | |
scripts/generate_info_json.sh | |
fi | |
- name: Set up Depot CLI | |
uses: depot/setup-action@v1 | |
- name: Login to DockerHub | |
uses: docker/login-action@v2 | |
with: | |
username: ${{ secrets.DOCKER_HUB_USERNAME }} | |
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} | |
- name: Build and push release image to Docker Hub | |
if: success() | |
uses: depot/build-push-action@v1 | |
with: | |
context: . | |
push: true | |
platforms: linux/arm64,linux/amd64 | |
build-args: | | |
APPSMITH_SEGMENT_CE_KEY=${{ secrets.APPSMITH_SEGMENT_CE_KEY_RELEASE }} | |
APPSMITH_CLOUD_SERVICES_BASE_URL=https://release-cs.appsmith.com | |
BASE=${{ vars.DOCKER_HUB_ORGANIZATION }}/base-${{ vars.EDITION }}:release | |
tags: | | |
${{ vars.DOCKER_HUB_ORGANIZATION }}/appsmith-${{ vars.EDITION }}:release | |
package-master: | |
needs: [ci-test, client-unit-tests, server-unit-tests] | |
runs-on: ubuntu-latest | |
# Set permissions since we're using OIDC token authentication between Depot and GitHub | |
permissions: | |
contents: read | |
id-token: write | |
# Run this job irrespective of tests failing, if this is the release branch; or only if the tests pass, if this is the master branch. | |
if: ( success() && github.ref == 'refs/heads/master' ) | |
steps: | |
- name: Checkout the head commit of the branch | |
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' | |
uses: actions/checkout@v4 | |
- name: Download the react build artifact | |
uses: actions/download-artifact@v3 | |
with: | |
name: client-build | |
path: app/client | |
- name: Unpack the client build artifact | |
if: steps.run_result.outputs.run_result != 'success' | |
run: | | |
mkdir -p app/client/build | |
tar -xvf app/client/build.tar -C app/client/build | |
- name: Download the server build artifact | |
uses: actions/download-artifact@v3 | |
with: | |
name: server-build | |
path: app/server/dist | |
- name: Download the rts build artifact | |
uses: actions/download-artifact@v3 | |
with: | |
name: rts-dist | |
path: app/client/packages/rts/dist | |
- name: Untar the rts folder | |
run: | | |
tar -xvf app/client/packages/rts/dist/rts-dist.tar -C app/client/packages/rts/ | |
echo "Cleaning up the tar files" | |
rm app/client/packages/rts/dist/rts-dist.tar | |
- name: Generate info.json | |
run: | | |
if [[ -f scripts/generate_info_json.sh ]]; then | |
scripts/generate_info_json.sh | |
fi | |
- name: Set up Depot CLI | |
uses: depot/setup-action@v1 | |
- name: Login to DockerHub | |
uses: docker/login-action@v2 | |
with: | |
username: ${{ secrets.DOCKER_HUB_USERNAME }} | |
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} | |
- name: Build and push master image to Docker Hub with commit tag | |
if: success() | |
uses: depot/build-push-action@v1 | |
with: | |
context: . | |
push: true | |
platforms: linux/arm64,linux/amd64 | |
build-args: | | |
APPSMITH_SEGMENT_CE_KEY=${{ secrets.APPSMITH_SEGMENT_CE_KEY }} | |
BASE=${{ vars.DOCKER_HUB_ORGANIZATION }}/base-${{ vars.EDITION }}:nightly | |
tags: | | |
${{ vars.DOCKER_HUB_ORGANIZATION }}/appsmith-${{ vars.EDITION }}:${{ github.sha }} | |
${{ vars.DOCKER_HUB_ORGANIZATION }}/appsmith-${{ vars.EDITION }}:nightly | |
notify-slack-for-promotion: | |
needs: ci-test | |
runs-on: ubuntu-latest | |
if: ( failure() && github.ref == 'refs/heads/master' ) | |
steps: | |
- name: Notify failure on workflow run and on Slack | |
run: | | |
set -o errexit | |
set -o nounset | |
set -o xtrace | |
run_url='${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/attempts/${{ github.run_attempt }}' | |
common_parent_sha='${{ steps.merge.outputs.common_parent_sha }}' | |
common_parent_sha_short="$(echo "$common_parent_sha" | grep -o '^.\{8\}' || true)" | |
merged_upto_sha='${{ steps.merge.outputs.merged_upto_sha }}' | |
merged_upto_sha_short="$(echo "$merged_upto_sha" | grep -o '^.\{8\}' || true)" | |
details="🚨 TBP workflow failed in <$run_url|${{ github.run_id }}/attempts/${{ github.run_attempt }}>." | |
# This unwieldy horror of a sed command, converts standard Markdown links to Slack's unwieldy link syntax. | |
slack_message=$(echo "$details" | sed -E 's/\[([^]]+)\]\(([^)]+)\)/<\2|\1>/g') | |
# This is the ChannelId of the tech channel. | |
body="$(jq -nc \ | |
--arg channel CGBPVEJ5C \ | |
--arg text "$slack_message" \ | |
'$ARGS.named' | |
)" | |
curl -v https://slack.com/api/chat.postMessage \ | |
--fail-with-body \ | |
--header 'Authorization: Bearer ${{ secrets.SLACK_APPSMITH_ALERTS_TOKEN }}' \ | |
--header 'Content-Type: application/json; charset=utf-8' \ | |
--data-raw "$body" |