diff --git a/.github/workflows/TestReuseActions.yml b/.github/workflows/TestReuseActions.yml new file mode 100644 index 0000000000..fca69cd784 --- /dev/null +++ b/.github/workflows/TestReuseActions.yml @@ -0,0 +1,1030 @@ +name: Test Reuse Actions + +on: + # This line enables manual triggering of this workflow. + workflow_dispatch: + + # trigger for pushes to release and master +# push: +# branches: [release, release-frozen, master] +# paths: +# - "app/client/**" +# - "app/server/**" +# - "app/rts/**" +# - "!app/client/cypress/manual_TestSuite/**" + +jobs: + buildClient: + # If the build has been triggered manually via workflow_dispatch or via a push to protected branches + # then we don't check for the PR approved state + if: | + github.event_name == 'workflow_dispatch' || + github.event_name == 'push' || + (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: + working-directory: app/client + shell: bash + + steps: + - name: Checkout the head commit of the branch + if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Figure out the PR number + run: echo ${{ github.event.pull_request.number }} + + # Timestamp will be used to create cache key + - id: timestamp + run: echo "::set-output name=timestamp::$(timestamp +'%Y-%m-%dT%H:%M:%S')" + + # In case this is second attempt try restoring status of the prior attempt from cache + - name: Restore the previous run result + uses: actions/cache@v2 + with: + path: | + ~/run_result + key: ${{ github.run_id }}-${{ github.job }}-${{ steps.timestamp.outputs.timestamp }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }}- + + # Fetch prior run result + - name: Get the previous run result + id: run_result + run: cat ~/run_result 2>/dev/null || echo 'default' + + #- uses: actions/checkout@v2 + # if: steps.run_result.outputs.run_result != 'success' + + # Incase of prior failure run the job + - if: steps.run_result.outputs.run_result != 'success' + run: echo "I'm alive!" && exit 0 + + # Set status = success + - run: echo "::set-output name=run_result::success" > ~/run_result + + - name: Checkout the merged commit from PR and base branch + if: github.event_name == 'pull_request_review' + uses: actions/checkout@v2 + with: + fetch-depth: 0 + ref: refs/pull/${{ github.event.pull_request.number }}/merge + + - name: Use Node.js 14.15.4 + if: steps.run_result.outputs.run_result != 'success' + uses: actions/setup-node@v1 + with: + node-version: "14.15.4" + + - name: Get yarn cache directory path + if: steps.run_result.outputs.run_result != 'success' + id: yarn-dep-cache-dir-path + run: echo "::set-output name=dir::$(yarn cache dir)" + + # Retrieve npm dependencies from cache. After a successful run, these dependencies are cached again + - name: Cache npm dependencies + if: steps.run_result.outputs.run_result != 'success' + id: yarn-dep-cache + uses: actions/cache@v2 + env: + cache-name: cache-yarn-dependencies + with: + path: | + ${{ steps.yarn-dep-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-dep-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn-dep- + + # Install all the dependencies + - name: Install dependencies + if: steps.run_result.outputs.run_result != 'success' + run: yarn install + + - name: Set the build environment based on the branch + if: steps.run_result.outputs.run_result != 'success' + id: vars + run: | + echo "::set-output name=REACT_APP_ENVIRONMENT::DEVELOPMENT" + if [[ "${{github.ref}}" == "refs/heads/master" ]]; then + echo "::set-output name=REACT_APP_ENVIRONMENT::PRODUCTION" + fi + if [[ "${{github.ref}}" == "refs/heads/release" ]]; then + echo "::set-output name=REACT_APP_ENVIRONMENT::STAGING" + fi + # Since this is an unreleased build, we set the version to incremented version number with + # a `-SNAPSHOT` suffix. + latest_released_version="$(git tag --list 'v*' --sort=-version:refname | head -1)" + echo "latest_released_version = $latest_released_version" + next_version="$(echo "$latest_released_version" | awk -F. -v OFS=. '{ $NF++; print }')" + echo "next_version = $next_version" + echo ::set-output name=version::$next_version-SNAPSHOT + + # We burn React environment & the Segment analytics key into the build itself. + # This is to ensure that we don't need to configure it in each installation + - name: Create the bundle + if: steps.run_result.outputs.run_result != 'success' + run: | + if [[ $GITHUB_REF == "refs/heads/release" ]]; then + REACT_APP_SEGMENT_CE_KEY=${{ secrets.APPSMITH_SEGMENT_CE_KEY_RELEASE }} + else + REACT_APP_SEGMENT_CE_KEY=${{ secrets.APPSMITH_SEGMENT_CE_KEY }} + fi + REACT_APP_ENVIRONMENT=${{steps.vars.outputs.REACT_APP_ENVIRONMENT}} \ + REACT_APP_FUSIONCHARTS_LICENSE_KEY=${{ secrets.APPSMITH_FUSIONCHARTS_LICENSE_KEY }} \ + REACT_APP_SEGMENT_CE_KEY="$REACT_APP_SEGMENT_CE_KEY" \ + SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} \ + REACT_APP_VERSION_ID=${{ steps.vars.outputs.version }} \ + REACT_APP_VERSION_RELEASE_DATE=$(date -u '+%Y-%m-%dT%H:%M:%SZ') \ + REACT_APP_GOOGLE_ANALYTICS_ID=${{ secrets.GOOGLE_TAG_MANAGER_ID }} \ + REACT_APP_INTERCOM_APP_ID=${{ secrets.APPSMITH_INTERCOM_ID }} \ + yarn build + ls -l build + + # Restore the previous built bundle if present. If not push the newly built into the cache + - name: Restore the previous bundle + uses: actions/cache@v2 + with: + path: | + app/client/build/ + key: ${{ github.run_id }}-${{ github.job }}-${{ steps.timestamp.outputs.timestamp }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }} + + # Upload the build artifact so that it can be used by the test & deploy job in the workflow + - name: Upload react build bundle + uses: actions/upload-artifact@v2 + with: + name: client-build + path: app/client/build/ + + # Set status = success + - run: echo "::set-output name=run_result::success" > ~/run_result + + buildServer: + defaults: + run: + working-directory: app/server + runs-on: ubuntu-latest + # Only run this workflow for internally triggered events + if: | + github.event_name == 'workflow_dispatch' || + github.event_name == 'push' || + (github.event_name == 'pull_request_review' && + github.event.review.state == 'approved' && + github.event.pull_request.head.repo.full_name == github.repository) + + # Service containers to run with this job. Required for running tests + services: + # Label used to access the service container + redis: + # Docker Hub image for Redis + image: redis + ports: + # Opens tcp port 6379 on the host and service container + - 6379:6379 + mongo: + image: mongo + ports: + - 27017:27017 + + steps: + # Checkout the code + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + + # Timestamp will be used to create cache key + - id: timestamp + run: echo "::set-output name=timestamp::$(timestamp +'%Y-%m-%dT%H:%M:%S')" + + # In case this is second attempt try restoring status of the prior attempt from cache + - name: Restore the previous run result + uses: actions/cache@v2 + with: + path: | + ~/run_result + key: ${{ github.run_id }}-${{ github.job }}-${{ steps.timestamp.outputs.timestamp }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }}- + + # Fetch prior run result + - name: Get the previous run result + id: run_result + run: cat ~/run_result 2>/dev/null || echo 'default' + + #- uses: actions/checkout@v2 + # if: steps.run_result.outputs.run_result != 'success' + + # Incase of prior failure run the job + - if: steps.run_result.outputs.run_result != 'success' + run: echo "I'm alive!" && exit 0 + + # Setup Java + - name: Set up JDK 1.11 + if: steps.run_result.outputs.run_result != 'success' + uses: actions/setup-java@v1 + with: + java-version: "11.0.10" + + # Retrieve maven dependencies from cache. After a successful run, these dependencies are cached again + - name: Cache maven dependencies + if: steps.run_result.outputs.run_result != 'success' + uses: actions/cache@v2 + env: + cache-name: cache-maven-dependencies + with: + # maven dependencies are stored in `~/.m2` on Linux/macOS + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + + # Here, the GITHUB_REF is of type /refs/head/. We extract branch_name from this by removing the + # first 11 characters. This can be used to build images for several branches + # Since this is an unreleased build, we get the latest released version number, increment the minor number in it, + # append a `-SNAPSHOT` at it's end to prepare the snapshot version number. This is used as the project's version. + - name: Get the version to tag the Docker image + if: steps.run_result.outputs.run_result != 'success' + id: vars + run: | + # Since this is an unreleased build, we set the version to incremented version number with a + # `-SNAPSHOT` suffix. + latest_released_version="$(git tag --list 'v*' --sort=-version:refname | head -1)" + echo "latest_released_version = $latest_released_version" + next_version="$(echo "$latest_released_version" | awk -F. -v OFS=. '{ $NF++; print }')" + echo "next_version = $next_version" + echo ::set-output name=version::$next_version-SNAPSHOT + echo ::set-output name=tag::$(echo ${GITHUB_REF:11}) + + - name: Test and Build package + if: steps.run_result.outputs.run_result != 'success' + env: + APPSMITH_MONGODB_URI: "mongodb://localhost:27017/mobtools" + APPSMITH_REDIS_URL: "redis://127.0.0.1:6379" + APPSMITH_ENCRYPTION_PASSWORD: "password" + APPSMITH_ENCRYPTION_SALT: "salt" + APPSMITH_IS_SELF_HOSTED: false + APPSMITH_GIT_ROOT: "./container-volumes/git-storage" + working-directory: app/server + run: | + mvn --batch-mode versions:set \ + -DnewVersion=${{ steps.vars.outputs.version }} \ + -DgenerateBackupPoms=false \ + -DprocessAllModules=true + ./build.sh -DskipTests + ls -l dist + + # Restore the previous built bundle if present. If not push the newly built into the cache + - name: Restore the previous bundle + uses: actions/cache@v2 + with: + path: | + app/server/dist/ + key: ${{ github.run_id }}-${{ github.job }}-${{ steps.timestamp.outputs.timestamp }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }} + + # Upload the build artifact so that it can be used by the test & deploy job in the workflow + - name: Upload server build bundle + uses: actions/upload-artifact@v2 + with: + name: server-build + path: app/server/dist/ + + - run: echo "::set-output name=run_result::success" > ~/run_result + + buildRts: + defaults: + run: + working-directory: app/rts + runs-on: ubuntu-latest + # Only run this workflow for internally triggered events + if: | + github.event_name == 'workflow_dispatch' || + github.event_name == 'push' || + (github.event_name == 'pull_request_review' && + github.event.review.state == 'approved' && + github.event.pull_request.head.repo.full_name == github.repository) + + steps: + # Checkout the code + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + + # Timestamp will be used to create cache key + - id: timestamp + run: echo "::set-output name=timestamp::$(timestamp +'%Y-%m-%dT%H:%M:%S')" + + # In case this is second attempt try restoring status of the prior attempt from cache + - name: Restore the previous run result + uses: actions/cache@v2 + with: + path: | + ~/run_result + key: ${{ github.run_id }}-${{ github.job }}-${{ steps.timestamp.outputs.timestamp }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }}- + + # Fetch prior run result + - name: Get the previous run result + id: run_result + run: cat ~/run_result 2>/dev/null || echo 'default' + + #- uses: actions/checkout@v2 + # if: steps.run_result.outputs.run_result != 'success' + + - if: steps.run_result.outputs.run_result != 'success' + run: echo "I'm alive!" && exit 0 + + - name: Use Node.js 14.15.4 + if: steps.run_result.outputs.run_result != 'success' + uses: actions/setup-node@v1 + with: + node-version: "14.15.4" + + # Here, the GITHUB_REF is of type /refs/head/. We extract branch_name from this by removing the + # first 11 characters. This can be used to build images for several branches + # Since this is an unreleased build, we get the latest released version number, increment the minor number in it, + # append a `-SNAPSHOT` at it's end to prepare the snapshot version number. This is used as the project's version. + - name: Get the version to tag the Docker image + if: steps.run_result.outputs.run_result != 'success' + id: vars + run: | + # Since this is an unreleased build, we set the version to incremented version number with a + # `-SNAPSHOT` suffix. + latest_released_version="$(git tag --list 'v*' --sort=-version:refname | head -1)" + echo "latest_released_version = $latest_released_version" + next_version="$(echo "$latest_released_version" | awk -F. -v OFS=. '{ $NF++; print }')" + echo "next_version = $next_version" + echo ::set-output name=version::$next_version-SNAPSHOT + echo ::set-output name=tag::$(echo ${GITHUB_REF:11}) + + - name: Build + if: steps.run_result.outputs.run_result != 'success' + run: | + echo 'export const VERSION = "${{ steps.vars.outputs.version }}"' > src/version.js + ./build.sh + ls -l dist + + # Restore the previous built bundle if present. If not push the newly built into the cache + - name: Restore the previous bundle + uses: actions/cache@v2 + with: + path: | + app/rts/dist/ + key: ${{ github.run_id }}-${{ github.job }}-${{ steps.timestamp.outputs.timestamp }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }} + + # Restore the previous built bundle if present. If not push the newly built into the cache + - name: Restore the previous bundle + uses: actions/cache@v2 + with: + path: | + app/rts/node_modules/ + key: ${{ github.run_id }}-${{ github.job }}-${{ steps.timestamp.outputs.timestamp }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }} + + # Upload the build artifact so that it can be used by the test & deploy job in the workflow + - name: Upload server build bundle + uses: actions/upload-artifact@v2 + with: + name: rts-build + path: app/rts/dist/ + + - name: Upload RTS dependencies bundle + uses: actions/upload-artifact@v2 + with: + name: rts-build-deps + path: app/rts/node_modules/ + + - run: echo "::set-output name=run_result::success" > ~/run_result + + ui-test: + needs: [buildClient, buildServer, buildRts] + # Only run if the build step is successful + # If the build has been triggered manually via workflow_dispatch or via a push to protected branches + # then we don't check for the PR approved state + if: | + success() && + (github.event_name == 'workflow_dispatch' || + github.event_name == 'push' || + (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: + working-directory: app/client + shell: bash + strategy: + fail-fast: false + matrix: + job: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23] + + # Service containers to run with this job. Required for running tests + services: + # Label used to access the service container + redis: + # Docker Hub image for Redis + image: redis + ports: + # Opens tcp port 6379 on the host and service container + - 6379:6379 + mongo: + image: mongo + ports: + - 27017:27017 + + steps: + # Checkout the code + - name: Checkout the merged commit from PR and base branch + if: github.event_name == 'pull_request_review' + uses: actions/checkout@v2 + with: + ref: refs/pull/${{ github.event.pull_request.number }}/merge + + - name: Checkout the head commit of the branch + if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' + uses: actions/checkout@v2 + + # Timestamp will be used to create cache key + - id: timestamp + run: echo "::set-output name=timestamp::$(timestamp +'%Y-%m-%dT%H:%M:%S')" + + # In case this is second attempt try restoring status of the prior attempt from cache + - name: Restore the previous run result + uses: martijnhols/actions-cache@v3 + with: + path: | + ~/run_result + key: ${{ github.run_id }}-${{ github.job }}-${{ steps.timestamp.outputs.timestamp }}-${{ matrix.job }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }}-${{ matrix.job }} + + # Fetch prior run result + - name: Get the previous run result + id: run_result + run: cat ~/run_result 2>/dev/null || echo 'default' + + # In case this is second attempt try restoring failed tests + - name: Restore the previous failed combine result + if: steps.run_result.outputs.run_result == 'failedtest' + uses: martijnhols/actions-cache/restore@v3 + with: + path: | + ~/combined_failed_spec + key: ${{ github.run_id }}-"ui-test-result"-${{ steps.timestamp.outputs.timestamp }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }} + + # failed_spec_env will contain list of all failed specs + # We are using evnironment variable instead of regular to support multiline + - name: Get failed_spec + if: steps.run_result.outputs.run_result == 'failedtest' + run: | + failed_spec_env=$(cat ~/combined_failed_spec) + echo "failed_spec_env<> $GITHUB_ENV + echo "$failed_spec_env" >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV + + #- uses: actions/checkout@v2 + # if: steps.run_result.outputs.run_result != 'success' + + - if: steps.run_result.outputs.run_result != 'success' + run: echo "Starting full run" && exit 0 + + - if: steps.run_result.outputs.run_result == 'failedtest' + run: echo "Rerunning failed tests" && exit 0 + + - name: cat run_result + run: echo ${{ steps.run_result.outputs.run_resultc }} + + # Setup Java + - name: Set up JDK 1.11 + if: steps.run_result.outputs.run_result != 'success' + uses: actions/setup-java@v1 + with: + java-version: "11.0.10" + + - name: Download the server build artifact + if: steps.run_result.outputs.run_result != 'success' + uses: actions/download-artifact@v2 + with: + name: server-build + path: app/server/dist + + # Retrieve maven dependencies from cache. After a successful run, these dependencies are cached again + - name: Cache maven dependencies + if: steps.run_result.outputs.run_result != 'success' + uses: actions/cache@v2 + env: + cache-name: cache-maven-dependencies + with: + # maven dependencies are stored in `~/.m2` on Linux/macOS + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + + # Here, the GITHUB_REF is of type /refs/head/. We extract branch_name from this by removing the + # first 11 characters. This can be used to build images for several branches + # Since this is an unreleased build, we get the latest released version number, increment the minor number in it, + # append a `-SNAPSHOT` at it's end to prepare the snapshot version number. This is used as the project's version. + - name: Get the version to tag the Docker image + if: steps.run_result.outputs.run_result != 'success' + id: vars + run: | + # Since this is an unreleased build, we set the version to incremented version number with a + # `-SNAPSHOT` suffix. + latest_released_version="$(git tag --list 'v*' --sort=-version:refname | head -1)" + echo "latest_released_version = $latest_released_version" + next_version="$(echo "$latest_released_version" | awk -F. -v OFS=. '{ $NF++; print }')" + echo "next_version = $next_version" + echo ::set-output name=version::$next_version-SNAPSHOT + echo ::set-output name=tag::$(echo ${GITHUB_REF:11}) + + # Start server + - name: Start server + if: steps.run_result.outputs.run_result != 'success' + working-directory: app/server + env: + APPSMITH_MONGODB_URI: "mongodb://localhost:27017/mobtools" + APPSMITH_REDIS_URL: "redis://127.0.0.1:6379" + APPSMITH_ENCRYPTION_PASSWORD: "password" + APPSMITH_ENCRYPTION_SALT: "salt" + APPSMITH_IS_SELF_HOSTED: false + APPSMITH_CLOUD_SERVICES_BASE_URL: "https://release-cs.appsmith.com" + APPSMITH_CLOUD_SERVICES_USERNAME: "" + APPSMITH_CLOUD_SERVICES_PASSWORD: "" + APPSMITH_GIT_ROOT: "./container-volumes/git-storage" + run: | + ls -l + ls -l scripts/ + ls -l dist/ + # Run the server in the background and redirect logs to a log file + ./scripts/start-dev-server.sh &> server-logs.log & + + - name: Wait for 30s and check if server is running + if: steps.run_result.outputs.run_result != 'success' + run: | + sleep 30s + if lsof -i :8080; then + echo "Server Found" + else + echo "Server Not Started. Printing logs from server process" + cat app/server/nohup.out + exit 1 + fi + + - name: Use Node.js 14.15.4 + if: steps.run_result.outputs.run_result != 'success' + uses: actions/setup-node@v1 + with: + node-version: "14.15.4" + + - name: Get yarn cache directory path + if: steps.run_result.outputs.run_result != 'success' + id: yarn-dep-cache-dir-path + run: echo "::set-output name=dir::$(yarn cache dir)" + + # Retrieve npm dependencies from cache. After a successful run, these dependencies are cached again + - name: Cache npm dependencies + if: steps.run_result.outputs.run_result != 'success' + id: yarn-dep-cache + uses: actions/cache@v2 + env: + cache-name: cache-yarn-dependencies + with: + path: | + ${{ steps.yarn-dep-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-dep-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn-dep- + + # Install all the dependencies + - name: Install dependencies + if: steps.run_result.outputs.run_result != 'success' + run: yarn install + + - name: Download the react build artifact + if: steps.run_result.outputs.run_result != 'success' + uses: actions/download-artifact@v2 + with: + name: client-build + path: app/client/build + + - name: Installing Yarn serve + if: steps.run_result.outputs.run_result != 'success' + run: | + yarn global add serve + echo "$(yarn global bin)" >> $GITHUB_PATH + + - name: Setting up the cypress tests + if: steps.run_result.outputs.run_result != 'success' + shell: bash + env: + APPSMITH_SSL_CERTIFICATE: ${{ secrets.APPSMITH_SSL_CERTIFICATE }} + APPSMITH_SSL_KEY: ${{ secrets.APPSMITH_SSL_KEY }} + CYPRESS_URL: ${{ secrets.CYPRESS_URL }} + CYPRESS_USERNAME: ${{ secrets.CYPRESS_USERNAME }} + CYPRESS_PASSWORD: ${{ secrets.CYPRESS_PASSWORD }} + CYPRESS_TESTUSERNAME1: ${{ secrets.CYPRESS_TESTUSERNAME1 }} + CYPRESS_TESTPASSWORD1: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_TESTUSERNAME2: ${{ secrets.CYPRESS_TESTUSERNAME2 }} + CYPRESS_TESTPASSWORD2: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_S3_ACCESS_KEY: ${{ secrets.CYPRESS_S3_ACCESS_KEY }} + CYPRESS_S3_SECRET_KEY: ${{ secrets.CYPRESS_S3_SECRET_KEY }} + APPSMITH_DISABLE_TELEMETRY: true + APPSMITH_GOOGLE_MAPS_API_KEY: ${{ secrets.APPSMITH_GOOGLE_MAPS_API_KEY }} + POSTGRES_PASSWORD: postgres + run: | + ./cypress/setup-test.sh + + # Onyl ru the below step if its a frist attempt + - name: Run the cypress test + if: steps.run_result.outputs.run_result != 'success' && steps.run_result.outputs.run_result != 'failedtest' + uses: cypress-io/github-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} + CYPRESS_PROJECT_ID: ${{ secrets.CYPRESS_PROJECT_ID }} + CYPRESS_USERNAME: ${{ secrets.CYPRESS_USERNAME }} + CYPRESS_PASSWORD: ${{ secrets.CYPRESS_PASSWORD }} + CYPRESS_TESTUSERNAME1: ${{ secrets.CYPRESS_TESTUSERNAME1 }} + CYPRESS_TESTPASSWORD1: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_TESTUSERNAME2: ${{ secrets.CYPRESS_TESTUSERNAME2 }} + CYPRESS_TESTPASSWORD2: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_S3_ACCESS_KEY: ${{ secrets.CYPRESS_S3_ACCESS_KEY }} + CYPRESS_S3_SECRET_KEY: ${{ secrets.CYPRESS_S3_SECRET_KEY }} + APPSMITH_DISABLE_TELEMETRY: true + APPSMITH_GOOGLE_MAPS_API_KEY: ${{ secrets.APPSMITH_GOOGLE_MAPS_API_KEY }} + COMMIT_INFO_MESSAGE: ${{ github.event.pull_request.title }} + with: + browser: chrome + headless: true + record: true + install: false + parallel: true + group: "Electrons on Github Action" + spec: "cypress/integration/Smoke_TestSuite/**/*" + working-directory: app/client + # tag will be either "push" or "pull_request" + tag: ${{ github.event_name }} + env: "NODE_ENV=development" + + # Incase of second attemtp only run failed specs + - name: Run the cypress test with failed tests + if: steps.run_result.outputs.run_result == 'failedtest' + uses: cypress-io/github-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} + CYPRESS_PROJECT_ID: ${{ secrets.CYPRESS_PROJECT_ID }} + CYPRESS_USERNAME: ${{ secrets.CYPRESS_USERNAME }} + CYPRESS_PASSWORD: ${{ secrets.CYPRESS_PASSWORD }} + CYPRESS_TESTUSERNAME1: ${{ secrets.CYPRESS_TESTUSERNAME1 }} + CYPRESS_TESTPASSWORD1: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_TESTUSERNAME2: ${{ secrets.CYPRESS_TESTUSERNAME2 }} + CYPRESS_TESTPASSWORD2: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_S3_ACCESS_KEY: ${{ secrets.CYPRESS_S3_ACCESS_KEY }} + CYPRESS_S3_SECRET_KEY: ${{ secrets.CYPRESS_S3_SECRET_KEY }} + APPSMITH_DISABLE_TELEMETRY: true + APPSMITH_GOOGLE_MAPS_API_KEY: ${{ secrets.APPSMITH_GOOGLE_MAPS_API_KEY }} + COMMIT_INFO_MESSAGE: ${{ github.event.pull_request.title }} + with: + browser: chrome + headless: true + record: true + install: false + parallel: true + group: "Electrons on Github Action" + spec: ${{ env.failed_spec_env }} + working-directory: app/client + # tag will be either "push" or "pull_request" + tag: ${{ github.event_name }} + env: "NODE_ENV=development" + + # Set status = failedtest + - name: Set fail if there are test failures + if: failure() + run: echo "::set-output name=run_result::failedtest" > ~/run_result + + # Create a directory ~/failed_spec and add a dummy file + # This will ensure upload and download steps are successfull + - name: Create direcotrs for failed tests + if: always() + run: | + mkdir -p ~/failed_spec + echo "empty" >> ~/failed_spec/dummy-${{ matrix.job }} + + # add list failed tests to a file + - name: Incase of test failures copy them to a file + if: failure() + run: | + cd /home/runner/work/appsmith/appsmith/app/client/cypress/ + find screenshots -type d|grep spec |sed 's/screenshots/cypress\/integration/g' > ~/failed_spec/failed_spec-${{ matrix.job }} + + # Upload failed test list using common path for all matrix job + - name: Upload failed test list artifact + if: always() + uses: actions/upload-artifact@v2 + with: + name: failed-spec + path: ~/failed_spec + + # Force store previous run result to cache + - name: Store the previous run result + if: failure() + uses: martijnhols/actions-cache/save@v3 + with: + path: | + ~/run_result + key: ${{ github.run_id }}-${{ github.job }}-${{ steps.timestamp.outputs.timestamp }}-${{ matrix.job }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }}-${{ matrix.job }} + + # Force store previous failed test list to cache + - name: Store the previous failed test result + if: failure() + uses: martijnhols/actions-cache/save@v3 + with: + path: | + ~/failed_spec + key: ${{ github.run_id }}-${{ github.job }}-${{ steps.timestamp.outputs.timestamp }}-${{ matrix.job }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }}-${{ matrix.job }} + + # Upload the screenshots as artifacts if there's a failure + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: cypress-screenshots-${{ matrix.job }} + path: app/client/cypress/screenshots/ + + - name: Restore the previous bundle + uses: actions/cache@v2 + with: + path: | + app/client/cypress/snapshots/ + key: ${{ github.run_id }}-${{ github.job }}-${{ steps.timestamp.outputs.timestamp }}-${{ matrix.job }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }}-${{ matrix.job }} + + # Upload the snapshots as artifacts for layout validation + - uses: actions/upload-artifact@v1 + with: + name: cypress-snapshots-visualRegression + path: app/client/cypress/snapshots/ + + # Upload the log artifact so that it can be used by the test & deploy job in the workflow + - name: Upload server logs bundle on failure + uses: actions/upload-artifact@v2 + if: failure() + with: + name: server-logs-${{ matrix.job }} + path: app/server/server-logs.log + + # Set status = success + - run: echo "::set-output name=run_result::success" > ~/run_result + + ui-test-result: + needs: ui-test + if: always() && + (github.event_name == 'workflow_dispatch' || + github.event_name == 'push' || + (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 ui-test matrices completed" + + # Download failed_spec list for all jobs + - uses: actions/download-artifact@v2 + if: needs.ui-test.result + id: download + with: + name: failed-spec + path: ~/failed_spec + + # Incase for any uti-test job failure, create combined failed spec + - name: "combine all specs" + if: needs.ui-test.result != 'success' + run: cat ~/failed_spec/failed_spec* >> ~/combined_failed_spec + + # Force save the failed spec list into a cache + - name: Store the combined run result + if: needs.ui-test.result + uses: martijnhols/actions-cache/save@v3 + with: + path: | + ~/combined_failed_spec + key: ${{ github.run_id }}-"ui-test-result"-${{ steps.timestamp.outputs.timestamp }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }} + + # Upload combined failed spec list to a file + # This is done for debugging. + - name: upload combined failed spec + if: needs.ui-test.result + uses: actions/upload-artifact@v2 + with: + name: combined_failed_spec + path: ~/combined_failed_spec + + - name: Return status for ui-matrix + run: | + if [[ "${{ needs.ui-test.result }}" == "success" ]]; then + echo "Integration tests completed successfully!"; + exit 0; + elif [[ "${{ needs.ui-test.result }}" == "skipped" ]]; then + echo "Integration tests were skipped"; + exit 1; + else + echo "Integration tests have failed"; + exit 1; + fi + + package: + needs: ui-test + runs-on: ubuntu-latest + + # 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') || + ( always() && + ( + github.event_name == 'workflow_dispatch' || + github.event_name == 'push' || + ( + github.event_name == 'pull_request_review' && + github.event.review.state == 'approved' && + github.event.pull_request.head.repo.full_name == github.repository + ) + ) && + github.ref == 'refs/heads/release' + ) + + steps: + # Checkout the code + - name: Checkout the merged commit from PR and base branch + if: github.event_name == 'pull_request_review' + uses: actions/checkout@v2 + with: + ref: refs/pull/${{ github.event.pull_request.number }}/merge + + - name: Checkout the head commit of the branch + if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' + uses: actions/checkout@v2 + + - name: Download the react build artifact + uses: actions/download-artifact@v2 + with: + name: client-build + path: app/client/build + + - name: Download the server build artifact + uses: actions/download-artifact@v2 + with: + name: server-build + path: app/server/dist + + - name: Download the rts build artifact + uses: actions/download-artifact@v2 + with: + name: rts-build + path: app/rts/dist + + - name: Download the rts build artifact + uses: actions/download-artifact@v2 + with: + name: rts-build-deps + path: app/rts/node_modules/ + + # Here, the GITHUB_REF is of type /refs/head/. We extract branch_name from this by removing the + # first 11 characters. This can be used to build images for several branches + - name: Get the version to tag the Docker image + id: vars + run: echo ::set-output name=tag::$(echo ${GITHUB_REF:11}) + + - name: Set up QEMU (needed for docker buildx) + uses: docker/setup-qemu-action@v1 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Login to DockerHub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + + # Build release Docker image and push to Docker Hub + # Commenting push + #- name: Push client release image to Docker Hub + # if: success() && github.ref == 'refs/heads/release' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') + # working-directory: app/client + # run: | + # docker build -t ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-editor:${{steps.vars.outputs.tag}} . + # docker push ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-editor:${{steps.vars.outputs.tag}} + + # Build master Docker image and push to Docker Hub + #- name: Push client master image to Docker Hub with commit tag + # if: success() && github.ref == 'refs/heads/master' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') + # working-directory: app/client + # run: | + # docker build -t ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-editor:${GITHUB_SHA} . + # docker build -t ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-editor:nightly . + # docker push ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-editor:${GITHUB_SHA} + # docker push ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-editor:nightly + + #- name: Build and push release image to Docker Hub + # if: success() && github.ref == 'refs/heads/release' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') + # working-directory: "." + # run: | + # tag_args="--tag ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-ce:${{steps.vars.outputs.tag}}" + # docker buildx build \ + # --platform linux/arm64,linux/amd64 \ + # --push \ + # --build-arg APPSMITH_SEGMENT_CE_KEY=${{ secrets.APPSMITH_SEGMENT_CE_KEY_RELEASE }} \ + # $tag_args \ + # . + + #- name: Build and push master image to Docker Hub with commit tag + # if: success() && github.ref == 'refs/heads/master' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') + # working-directory: "." + # run: | + # tag_args="--tag ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-ce:${GITHUB_SHA}" + # tag_args="$tag_args --tag ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-ce:nightly" + # docker buildx build \ + # --platform linux/arm64,linux/amd64 \ + # --push \ + # --build-arg APPSMITH_SEGMENT_CE_KEY=${{ secrets.APPSMITH_SEGMENT_CE_KEY }} \ + # $tag_args \ + # . + + # - name: Check and push fat image to Docker Hub with commit tag + # if: success() && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/release') && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') + # working-directory: "." + # run: | + # if [[ "${{ github.ref }}" == "refs/heads/master" ]]; then + # tag=nightly + # else + # tag="${{ steps.vars.outputs.tag }}" + # fi + # docker run --detach --publish 80:80 --name appsmith \ + # "${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-ce:$tag" + # sleep 180 + # cd deploy/docker + # if bash run-test.sh; then + # echo "Fat container test passed. Pushing image." + # docker push --all-tags ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-ce + # else + # echo "Fat container test FAILED. Not pushing image." + # # Temporarily pushing even if test fails. + # docker push --all-tags ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-ce + # fi + + # Build release Docker image and push to Docker Hub + #- name: Push server release image to Docker Hub + # if: success() && github.ref == 'refs/heads/release' + # working-directory: app/server + # run: | + # docker build --build-arg APPSMITH_SEGMENT_CE_KEY=${{ secrets.APPSMITH_SEGMENT_CE_KEY_RELEASE }} -t ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-server:${{steps.vars.outputs.tag}} . + # docker push ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-server:${{steps.vars.outputs.tag}} + + # Build master Docker image and push to Docker Hub + #- name: Push server master image to Docker Hub with commit tag + # if: success() && github.ref == 'refs/heads/master' + # working-directory: app/server + # run: | + # docker build --build-arg APPSMITH_SEGMENT_CE_KEY=${{ secrets.APPSMITH_SEGMENT_CE_KEY }} -t ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-server:${GITHUB_SHA} . + # docker build --build-arg APPSMITH_SEGMENT_CE_KEY=${{ secrets.APPSMITH_SEGMENT_CE_KEY }} -t ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-server:nightly . + # docker push ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-server:${GITHUB_SHA} + # docker push ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-server:nightly + + # Build release Docker image and push to Docker Hub + #- name: Push RTS release image to Docker Hub + # if: success() && github.ref == 'refs/heads/release' + # working-directory: app/rts + # run: | + # docker build -t ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-rts:${{steps.vars.outputs.tag}} . + # docker push ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-rts:${{steps.vars.outputs.tag}} + + # Build master Docker image and push to Docker Hub + #- name: Push RTS master image to Docker Hub with commit tag + # if: success() && github.ref == 'refs/heads/master' + # working-directory: app/rts + # run: | + # docker build -t ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-rts:${GITHUB_SHA} . + # docker build -t ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-rts:nightly . + # docker push ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-rts:${GITHUB_SHA} + # docker push ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-rts:nightly