diff --git a/.github/workflows/build-rts.yml b/.github/workflows/build-rts.yml deleted file mode 100644 index 88e13583c9..0000000000 --- a/.github/workflows/build-rts.yml +++ /dev/null @@ -1,111 +0,0 @@ -# This workflow is responsible for building, testing & packaging the RTS Node server. -name: Build RTS Workflow - -on: - # This line enables manual triggering of this workflow. - workflow_dispatch: - - push: - branches: [release, master] - # Only trigger if files have changed in this specific path - paths: - - "app/rts/**" - - pull_request: - branches: [release, master] - paths: - - "app/rts/**" - -# Change the working directory for all the jobs in this workflow -defaults: - run: - working-directory: app/rts - -jobs: - build: - runs-on: ubuntu-latest - # Only run this workflow for internally triggered events - if: | - github.event.pull_request.head.repo.full_name == github.repository || - github.event_name == 'push' || - github.event_name == 'workflow_dispatch' - - steps: - # Checkout the code - - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - - name: Use Node.js 16.14.0 - uses: actions/setup-node@v1 - with: - node-version: "16.14.0" - - # 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 - 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 - run: ./build.sh - - # Build release Docker image and push to Docker Hub - - name: Push release image to Docker Hub - if: success() && github.ref == 'refs/heads/release' - run: | - docker build -t ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-rts:${{steps.vars.outputs.tag}} . - echo ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} | docker login -u ${{ secrets.DOCKER_HUB_USERNAME }} --password-stdin - docker push ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-rts:${{steps.vars.outputs.tag}} - - # Build master Docker image and push to Docker Hub - - name: Push master image to Docker Hub with commit tag - if: success() && github.ref == 'refs/heads/master' - run: | - docker build -t ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-rts:${GITHUB_SHA} . - docker build -t ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-rts:nightly . - echo ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} | docker login -u ${{ secrets.DOCKER_HUB_USERNAME }} --password-stdin - docker push ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-rts:${GITHUB_SHA} - docker push ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-rts:nightly - - # These are dummy jobs in the CI build to satisfy required status checks for merging PRs. This is a hack because Github doesn't support conditional - # required checks in monorepos. These jobs are a clone of similarly named jobs in client.yml. - # - # Check support request at: https://github.community/t/feature-request-conditional-required-checks/16761 - ui-test: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - job: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] - - steps: - # Checkout the code - - uses: actions/checkout@v2 - - - name: Do nothing as this is a dummy step - shell: bash - run: | - exit 0 - - package: - runs-on: ubuntu-latest - - steps: - # Checkout the code - - uses: actions/checkout@v2 - - - name: Do nothing as this is a dummy step - shell: bash - run: | - exit 0 diff --git a/.github/workflows/client-build.yml b/.github/workflows/client-build.yml index 5b31197cc2..85d7fa41d6 100644 --- a/.github/workflows/client-build.yml +++ b/.github/workflows/client-build.yml @@ -3,13 +3,12 @@ name: Appsmith Client Build Workflow on: # This line enables manual triggering of this workflow. workflow_dispatch: - - push: - branches: [release, master] - # Only trigger if files have changed in this specific path - paths: - - "app/client/**" - - "!app/client/cypress/manual_TestSuite/**" + workflow_call: + inputs: + pr: + description: "This is the PR number in case the workflow is being called in a pull request" + required: false + type: number pull_request: branches: [release, master] @@ -25,49 +24,84 @@ defaults: jobs: build: runs-on: buildjet-8vcpu-ubuntu-2004 - # Only run for internal PRs or commits to release or master + # Only run this workflow for internally triggered events if: | - github.event.pull_request.head.repo.full_name == github.repository || + github.event.pull_request.head.repo.full_name == github.repository || github.event_name == 'push' || - github.event_name == 'workflow_dispatch' + github.event_name == 'workflow_dispatch' || + github.event_name == 'repository_dispatch' defaults: run: working-directory: app/client shell: bash steps: - # Checkout the code + # The checkout steps MUST happen first because the default directory is set according to the code base. + # Github Action expects all future commands to be executed in the code directory. Hence, we need to check out + # the code before doing anything else. + + # Check out merge commit with the base branch in case this workflow is invoked via pull request - name: Checkout the merged commit from PR and base branch - if: github.event_name == 'pull_request' + if: inputs.pr != 0 uses: actions/checkout@v2 with: fetch-depth: 0 - ref: refs/pull/${{ github.event.pull_request.number }}/merge + ref: refs/pull/${{ inputs.pr }}/merge + # Checkout the code in the current branch in case the workflow is called because of a branch push event - name: Checkout the head commit of the branch - if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' + if: inputs.pr == 0 uses: actions/checkout@v2 with: fetch-depth: 0 - name: Figure out the PR number - run: echo ${{ github.event.pull_request.number }} + run: echo ${{ inputs.pr }} + + - name: Print the Github event + run: echo ${{ github.event_name }} + + # 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' + + # Incase of prior failure run the job + - if: steps.run_result.outputs.run_result != 'success' + run: echo "I'm alive!" && exit 0 - name: Use Node.js 16.14.0 + if: steps.run_result.outputs.run_result != 'success' uses: actions/setup-node@v1 with: node-version: "16.14.0" - 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 + cache-name: client-cache-yarn-dependencies with: path: | ${{ steps.yarn-dep-cache-dir-path.outputs.dir }} @@ -77,9 +111,11 @@ jobs: # Install all the dependencies - name: Install dependencies + if: steps.run_result.outputs.run_result != 'success' run: yarn install --frozen-lockfile - 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" @@ -97,8 +133,9 @@ jobs: echo "next_version = $next_version" echo ::set-output name=version::$next_version-SNAPSHOT + # Run the Jest tests only if the workflow has been invoked in a PR and the previous re-run has failed - name: Run the jest tests - if: github.event_name == 'pull_request' + if: steps.run_result.outputs.run_result != 'success' && inputs.pr != 0 run: REACT_APP_ENVIRONMENT=${{steps.vars.outputs.REACT_APP_ENVIRONMENT}} yarn run test:unit # We burn React environment & the Segment analytics key into the build itself. @@ -114,9 +151,22 @@ jobs: REACT_APP_VERSION_EDITION="Community" \ yarn 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: build path: app/client/build/ + + # Set status = success + - run: echo "::set-output name=run_result::success" > ~/run_result diff --git a/.github/workflows/integration-tests-command.yml b/.github/workflows/integration-tests-command.yml index 0226a24b76..4052042a66 100644 --- a/.github/workflows/integration-tests-command.yml +++ b/.github/workflows/integration-tests-command.yml @@ -7,435 +7,25 @@ on: jobs: server-build: - runs-on: buildjet-8vcpu-ubuntu-2004 - if: | - github.event_name == 'repository_dispatch' && - github.event.client_payload.slash_command.sha != '' && - contains(github.event.client_payload.pull_request.head.sha, github.event.client_payload.slash_command.sha) - defaults: - run: - working-directory: app/server - shell: bash + name: server-build + uses: ./.github/workflows/server-build.yml + with: + pr: ${{ github.event.client_payload.pull_request.number }} - # 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 + client-build: + name: client-build + uses: ./.github/workflows/client-build.yml + with: + pr: ${{ github.event.client_payload.pull_request.number }} - steps: - # Check out merge commit - - name: Fork based /ok-to-test checkout - uses: actions/checkout@v2 - with: - ref: "refs/pull/${{ github.event.client_payload.pull_request.number }}/merge" - - # 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' - - # 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 - 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}) - - # Build and test the code - - name: Build and test - if: steps.run_result.outputs.run_result != 'success' - env: - APPSMITH_MONGODB_URI: "mongodb://localhost:27017/mobtools" - APPSMITH_CLOUD_SERVICES_BASE_URL: "https://release-cs.appsmith.com" - 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" - run: | - ./build.sh versions:set \ - -DnewVersion=${{ steps.vars.outputs.version }} \ - -DgenerateBackupPoms=false \ - -DprocessAllModules=true - - # 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: build - path: app/server/dist/ - - # Set status = success - - run: echo "::set-output name=run_result::success" > ~/run_result - - build: - runs-on: buildjet-8vcpu-ubuntu-2004 - if: github.event_name == 'repository_dispatch' && - github.event.client_payload.slash_command.sha != '' && - contains(github.event.client_payload.pull_request.head.sha, github.event.client_payload.slash_command.sha) - defaults: - run: - working-directory: app/client - shell: bash - - steps: - # Check out merge commit - - name: Fork based /ok-to-test checkout - uses: actions/checkout@v2 - with: - ref: "refs/pull/${{ github.event.client_payload.pull_request.number }}/merge" - - - name: Figure out the PR number - run: echo ${{ github.event.client_payload.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' - - # 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 - - # This step creates a comment on the PR with a link to this workflow run. - - name: Add a comment on the PR with link to workflow run - if: steps.run_result.outputs.run_result != 'success' - uses: peter-evans/create-or-update-comment@v1 - with: - issue-number: ${{ github.event.client_payload.pull_request.number }} - body: | - Tests running at: . - Workflow: `${{ github.workflow }}`. - Commit: `${{ github.event.client_payload.slash_command.sha }}`. - PR: ${{ github.event.client_payload.pull_request.number }}. - - - name: Use Node.js 16.14.0 - if: steps.run_result.outputs.run_result != 'success' - uses: actions/setup-node@v1 - with: - node-version: "16.14.0" - - - 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 --frozen-lockfile - - - 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 - - - name: Run the jest tests - if: steps.run_result.outputs.run_result != 'success' - run: REACT_APP_ENVIRONMENT=${{steps.vars.outputs.REACT_APP_ENVIRONMENT}} yarn run test:unit - - # 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: | - REACT_APP_ENVIRONMENT=${{steps.vars.outputs.REACT_APP_ENVIRONMENT}} \ - REACT_APP_FUSIONCHARTS_LICENSE_KEY=${{ secrets.APPSMITH_FUSIONCHARTS_LICENSE_KEY }} \ - REACT_APP_SEGMENT_CE_KEY=${{ secrets.APPSMITH_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_VERSION_EDITION="Community" \ - yarn 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: build - path: app/client/build/ - - # Update check run called "build" - - name: Mark build job as complete - uses: actions/github-script@v1 - id: update-check-run - if: ${{ always() }} - env: - run_id: ${{ github.run_id }} - repository: ${{ github.repository }} - number: ${{ github.event.client_payload.pull_request.number }} - job: ${{ github.job }} - # Conveniently, job.status maps to https://developer.github.com/v3/checks/runs/#update-a-check-run - conclusion: ${{ job.status }} - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { data: pull } = await github.pulls.get({ - ...context.repo, - pull_number: process.env.number - }); - const ref = pull.head.sha; - - const { data: checks } = await github.checks.listForRef({ - ...context.repo, - ref - }); - - const check = checks.check_runs.filter(c => c.name === process.env.job); - - if(check.length == 0) { - const head_sha = pull.head.sha; - const { data: completed_at } = await github.checks.create({ - owner: context.repo.owner, - repo: context.repo.repo, - head_sha: head_sha, - name: process.env.job, - status: 'completed', - conclusion: process.env.conclusion, - output: { - title: "Build client result for ok to test", - summary: "https://github.com/" + process.env.repository + "/actions/runs/" + process.env.run_id - } - }); - - return completed_at; - } else { - const { data: result } = await github.checks.update({ - ...context.repo, - check_run_id: check[0].id, - status: 'completed', - conclusion: process.env.conclusion, - output: { - title: "Build client result for ok to test", - summary: "https://github.com/" + process.env.repository + "/actions/runs/" + process.env.run_id - } - }); - - return result; - } - - # Set status = success - - 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 == 'repository_dispatch' && - github.event.client_payload.slash_command.sha != '' && - contains(github.event.client_payload.pull_request.head.sha, github.event.client_payload.slash_command.sha) - - 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' - - # Incase of prior failure run the job - - if: steps.run_result.outputs.run_result != 'success' - run: echo "I'm alive!" && exit 0 - - - name: Use Node.js 16.14.0 - if: steps.run_result.outputs.run_result != 'success' - uses: actions/setup-node@v1 - with: - node-version: "16.14.0" - - # 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/ + rts-build: + name: rts-build + uses: ./.github/workflows/rts-build.yml + with: + pr: ${{ github.event.client_payload.pull_request.number }} fat-container-test: - needs: [build, server-build, buildRts] + needs: [client-build, server-build, rts-build] # Only run if the build step is successful if: success() runs-on: ubuntu-latest @@ -542,12 +132,6 @@ jobs: 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/ - - name: Build docker image if: steps.run_result.outputs.run_result != 'success' working-directory: "." @@ -800,7 +384,7 @@ jobs: - run: echo "::set-output name=run_result::success" > ~/run_result ui-test: - needs: [build, server-build] + needs: [client-build, server-build, rts-build] # Only run if the build step is successful if: success() runs-on: ubuntu-latest @@ -1296,6 +880,8 @@ jobs: PAYLOAD_CONTEXT: ${{ toJson(github.event.client_payload) }} run: echo "$PAYLOAD_CONTEXT" +<<<<<<< HEAD +======= package: needs: [ui-test, fat-container-test] runs-on: buildjet-4vcpu-ubuntu-2004 @@ -1364,10 +950,17 @@ jobs: return result; } +>>>>>>> 4d609a5b4d5e203c84aba12475a44ac6770eff0d perf-test: - needs: [build, server-build] + needs: [client-build, server-build, rts-build] # Only run if the build step is successful if: success() +<<<<<<< HEAD + name: perf-test + uses: ./.github/workflows/perf-test.yml + with: + pr: ${{ github.event.client_payload.pull_request.number }} +======= runs-on: buildjet-4vcpu-ubuntu-2004 defaults: @@ -1599,3 +1192,4 @@ jobs: # Set status = success - run: echo "::set-output name=run_result::success" > ~/run_result +>>>>>>> 4d609a5b4d5e203c84aba12475a44ac6770eff0d diff --git a/.github/workflows/ok-to-test.yml b/.github/workflows/ok-to-test.yml index 5defa03db6..7f1da6561a 100644 --- a/.github/workflows/ok-to-test.yml +++ b/.github/workflows/ok-to-test.yml @@ -20,13 +20,14 @@ jobs: private_key: ${{ secrets.APPSMITH_INTEGRATION_TESTING_KEY }} - name: Slash Command Dispatch - uses: peter-evans/slash-command-dispatch@v1 + uses: peter-evans/slash-command-dispatch@v3 env: TOKEN: ${{ steps.generate_token.outputs.token }} with: token: ${{ env.TOKEN }} # GitHub App installation access token reaction-token: ${{ secrets.GITHUB_TOKEN }} issue-type: pull-request - commands: ok-to-test - named-args: true + commands: | + ok-to-test + perf-test permission: write diff --git a/.github/workflows/perf-test.yml b/.github/workflows/perf-test.yml new file mode 100644 index 0000000000..e4f59281e6 --- /dev/null +++ b/.github/workflows/perf-test.yml @@ -0,0 +1,263 @@ +name: Appsmith Performance Test Workflow + +on: + # This line enables manual triggering of this workflow. + workflow_dispatch: + workflow_call: + inputs: + pr: + description: "This is the PR number in case the workflow is being called in a pull request" + required: false + type: number + repository_dispatch: + types: [perf-test-command] + +# Change the working directory for all the jobs in this workflow +defaults: + run: + working-directory: app/client + shell: bash + +jobs: + perf-test: + runs-on: ubuntu-latest + # Only run this workflow for internally triggered events + if: | + github.event.pull_request.head.repo.full_name == github.repository || + github.event_name == 'push' || + github.event_name == 'workflow_dispatch' || + github.event_name == 'repository_dispatch' + defaults: + run: + working-directory: app/client + shell: bash + + # 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: + # Check out merge commit between the PR branch & base branch + - name: Fork based /perf-test checkout + uses: actions/checkout@v2 + with: + ref: "refs/pull/${{ github.event.client_payload.pull_request.number }}/merge" + + - name: Figure out the PR number + run: echo ${{ inputs.pr }} + + - name: Print the Github event + run: echo ${{ github.event_name }} + + # 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' + + # 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: Use Node.js 16.14.0 + if: steps.run_result.outputs.run_result != 'success' + uses: actions/setup-node@v1 + with: + node-version: "16.14.0" + + - 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 --frozen-lockfile + + - name: Download the react build artifact + if: steps.run_result.outputs.run_result != 'success' + uses: actions/download-artifact@v2 + with: + name: build + path: app/client/build + + - name: Download the server build artifact + if: steps.run_result.outputs.run_result != 'success' + uses: actions/download-artifact@v2 + with: + name: build + path: app/server/dist + + # 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 30 seconds for server to start + if: steps.run_result.outputs.run_result != 'success' + run: | + sleep 30s + + - name: Exit if Server hasnt started + if: steps.run_result.outputs.run_result != 'success' + run: | + if [[ `ps -ef | grep "server-1.0-SNAPSHOT" | grep java |wc -l` == 0 ]]; then + echo "Server Not Started"; + exit 1; + else + echo "Server Found"; + fi + + - 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 perf 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 }} + CYPRESS_APPSMITH_OAUTH2_GOOGLE_CLIENT_ID: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_GOOGLE_CLIENT_ID }} + CYPRESS_APPSMITH_OAUTH2_GOOGLE_CLIENT_SECRET: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_GOOGLE_CLIENT_SECRET }} + CYPRESS_APPSMITH_OAUTH2_GITHUB_CLIENT_ID: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_GITHUB_CLIENT_ID }} + CYPRESS_APPSMITH_OAUTH2_GITHUB_CLIENT_SECRET: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_GITHUB_CLIENT_SECRET }} + APPSMITH_DISABLE_TELEMETRY: true + APPSMITH_GOOGLE_MAPS_API_KEY: ${{ secrets.APPSMITH_GOOGLE_MAPS_API_KEY }} + POSTGRES_PASSWORD: postgres + run: | + ./cypress/setup-test.sh + + - name: Checkout Performance Infra code + uses: actions/checkout@v3 + with: + repository: appsmithorg/performance-infra + token: ${{ secrets.APPSMITH_PERF_INFRA_REPO_PAT }} + ref: main + path: app/client/perf + + - name: Installing performance tests dependencies + if: steps.run_result.outputs.run_result != 'success' + working-directory: app/client/perf + shell: bash + run: yarn install --frozen-lockfile + + - name: Change test script permissions + if: steps.run_result.outputs.run_result != 'success' + working-directory: app/client/perf + run: chmod +x ./start-test.sh + + - name: Run performance tests + if: steps.run_result.outputs.run_result != 'success' + working-directory: app/client/perf + shell: bash + env: + APPSMITH_SSL_CERTIFICATE: ${{ secrets.APPSMITH_SSL_CERTIFICATE }} + APPSMITH_SSL_KEY: ${{ secrets.APPSMITH_SSL_KEY }} + CYPRESS_TESTUSERNAME1: ${{ secrets.CYPRESS_TESTUSERNAME9 }} + CYPRESS_TESTPASSWORD1: ${{ secrets.CYPRESS_TESTPASSWORD9 }} + APPSMITH_PERF_SUPABASE_SECRET: ${{ secrets.APPSMITH_PERF_SUPABASE_SECRET }} + APPSMITH_DISABLE_TELEMETRY: true + POSTGRES_PASSWORD: postgres + NODE_TLS_REJECT_UNAUTHORIZED: "0" + run: ./start-test.sh + + # 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/perf/traces + key: ${{ github.run_id }}-${{ github.job }}-${{ steps.timestamp.outputs.timestamp }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }} + + - uses: actions/upload-artifact@v2 + with: + name: performance-summaries + path: app/client/perf/traces + + - name: Read summary file + id: read_summary + uses: andstor/file-reader-action@v1 + with: + path: app/client/perf/traces/reports/summary.md + + - name: Add a comment with the results on the PR with link to workflow run + uses: peter-evans/create-or-update-comment@v1 + with: + issue-number: ${{ github.event.client_payload.pull_request.number }} + body: | + UI Performance test run logs and artifacts: . + Commit: `${{ github.event.client_payload.slash_command.sha }}`. + Results: ${{ steps.read_summary.outputs.contents }} + + # Set status = success + - run: echo "::set-output name=run_result::success" > ~/run_result diff --git a/.github/workflows/rts-build.yml b/.github/workflows/rts-build.yml new file mode 100644 index 0000000000..e8655e58dd --- /dev/null +++ b/.github/workflows/rts-build.yml @@ -0,0 +1,149 @@ +# This workflow is responsible for building, testing & packaging the RTS Node server. +name: Build RTS Workflow + +on: + # This line enables manual triggering of this workflow. + workflow_dispatch: + workflow_call: + inputs: + pr: + description: "This is the PR number in case the workflow is being called in a pull request" + required: false + type: number + + pull_request: + branches: [release, master] + paths: + - "app/rts/**" + +# Change the working directory for all the jobs in this workflow +defaults: + run: + working-directory: app/rts + +jobs: + build: + runs-on: ubuntu-latest + # Only run this workflow for internally triggered events + if: | + github.event.pull_request.head.repo.full_name == github.repository || + github.event_name == 'push' || + github.event_name == 'workflow_dispatch' || + github.event_name == 'repository_dispatch' + + steps: + # The checkout steps MUST happen first because the default directory is set according to the code base. + # Github Action expects all future commands to be executed in the code directory. Hence, we need to check out + # the code before doing anything else. + + # Check out merge commit with the base branch in case this workflow is invoked via pull request + - name: Checkout the merged commit from PR and base branch + if: inputs.pr != 0 + uses: actions/checkout@v2 + with: + fetch-depth: 0 + ref: refs/pull/${{ inputs.pr }}/merge + + # Checkout the code in the current branch in case the workflow is called because of a branch push event + - name: Checkout the head commit of the branch + if: inputs.pr == 0 + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Figure out the PR number + run: echo ${{ inputs.pr }} + + - name: Print the Github event + run: echo ${{ github.event_name }} + + # 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' + + # Incase of prior failure run the job + - if: steps.run_result.outputs.run_result != 'success' + run: echo "I'm alive!" && exit 0 + + - name: Use Node.js 16.14.0 + if: steps.run_result.outputs.run_result != 'success' + uses: actions/setup-node@v1 + with: + node-version: "16.14.0" + + - 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: client-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- + + # 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 + + # 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 }} + + # Upload the build artifact so that it can be used by the test & deploy job in other workflows + - name: Upload rts build bundle + uses: actions/upload-artifact@v2 + with: + name: rts-build + path: app/rts/dist/ + + # Set status = success + - run: echo "::set-output name=run_result::success" > ~/run_result diff --git a/.github/workflows/server.yml b/.github/workflows/server-build.yml similarity index 51% rename from .github/workflows/server.yml rename to .github/workflows/server-build.yml index b732eca017..81e7088c56 100644 --- a/.github/workflows/server.yml +++ b/.github/workflows/server-build.yml @@ -4,12 +4,12 @@ name: Appsmith Server Workflow on: # This line enables manual triggering of this workflow. workflow_dispatch: - - push: - branches: [release, master] - # Only trigger if files have changed in this specific path - paths: - - "app/server/**" + workflow_call: + inputs: + pr: + description: "This is the PR number in case the workflow is being called in a pull request" + required: false + type: number pull_request: branches: [release, master] @@ -28,7 +28,8 @@ jobs: if: | github.event.pull_request.head.repo.full_name == github.repository || github.event_name == 'push' || - github.event_name == 'workflow_dispatch' + github.event_name == 'workflow_dispatch' || + github.event_name == 'repository_dispatch' # Service containers to run with this job. Required for running tests services: @@ -41,19 +42,64 @@ jobs: - 6379:6379 steps: - # Checkout the code - - uses: actions/checkout@v2 + # The checkout steps MUST happen first because the default directory is set according to the code base. + # Github Action expects all future commands to be executed in the code directory. Hence, we need to check out + # the code before doing anything else. + + # Check out merge commit with the base branch in case this workflow is invoked via pull request + - name: Check out merged commit from PR and base branch + uses: actions/checkout@v2 + if: inputs.pr != 0 + with: + fetch-depth: 0 + ref: refs/pull/${{ inputs.pr }}/merge + + # Checkout the code in the current branch in case the workflow is called because of a branch push event + - name: Check out the head commit of the branch + uses: actions/checkout@v2 + if: inputs.pr == 0 with: fetch-depth: 0 + - name: Figure out the PR number + run: echo ${{ inputs.pr }} + + - name: Print the Github event + run: echo ${{ github.event_name }} + + # 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' + + # 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 @@ -68,6 +114,7 @@ jobs: # 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 @@ -81,6 +128,7 @@ jobs: # Build and test the code - name: Build and test + if: steps.run_result.outputs.run_result != 'success' env: APPSMITH_MONGODB_URI: "mongodb://localhost:27017/mobtools" APPSMITH_CLOUD_SERVICES_BASE_URL: "https://release-cs.appsmith.com" @@ -95,14 +143,21 @@ jobs: -DprocessAllModules=true ./build.sh - package: - runs-on: ubuntu-latest + # 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 }} - steps: - # Checkout the code - - uses: actions/checkout@v2 + # 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: build + path: app/server/dist/ - - name: Do nothing as this is a dummy step - shell: bash - run: | - exit 0 + - run: echo "::set-output name=run_result::success" > ~/run_result diff --git a/.github/workflows/test-build-docker-image.yml b/.github/workflows/test-build-docker-image.yml index cb1df9bfd2..5ec19ca16f 100644 --- a/.github/workflows/test-build-docker-image.yml +++ b/.github/workflows/test-build-docker-image.yml @@ -71,9 +71,6 @@ jobs: 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 diff --git a/app/client/README.md b/app/client/README.md index d32bc553a5..97738e1dee 100755 --- a/app/client/README.md +++ b/app/client/README.md @@ -2,3 +2,4 @@ This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).

For details on setting up your development machine, please refer to the [Setup Guide](../../contributions/ClientSetup.md) + diff --git a/app/rts/README.md b/app/rts/README.md new file mode 100644 index 0000000000..d19bbe420d --- /dev/null +++ b/app/rts/README.md @@ -0,0 +1,3 @@ +# Appsmith Realtime Server + +This is the code for the Appsmith realtime server. diff --git a/app/server/README.md b/app/server/README.md index bfb384ae20..58eafff4dc 100644 --- a/app/server/README.md +++ b/app/server/README.md @@ -1,4 +1,5 @@ # Appsmith Server + This is the server-side repository for the Appsmith framework.

-For details on setting up your development machine, please refer to the [Setup Guide](../../contributions/ServerSetup.md) +For details on setting up your development machine, please refer to this [Setup Guide](../../contributions/ServerSetup.md).