diff --git a/.github/workflows/deploy_production.yml b/.github/workflows/deploy_production.yml index 10f5a53..7062b09 100644 --- a/.github/workflows/deploy_production.yml +++ b/.github/workflows/deploy_production.yml @@ -1,96 +1,95 @@ name: Deploy on production -on: +on: push: branches: - - "production" + - "production" -env: +env: MONGO_VERSION: 8.0.3 UBUNTU_VERSION: linux-x86_64-ubuntu2004 - # name of the binary, the service and the user running the - # service + # name of the binary, the service and the user running the + # service APP_NAME: mongoplayground jobs: - deploy: runs-on: ubuntu-20.04 environment: production steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version: '1.23' - - - name: Vet code - run: go vet ./... - - - name: Download MongoDB and setup standalone db - run: | - wget --quiet http://downloads.mongodb.org/linux/mongodb-$UBUNTU_VERSION-$MONGO_VERSION.tgz - tar xzvf mongodb-$UBUNTU_VERSION-$MONGO_VERSION.tgz - echo "$PWD/mongodb-$UBUNTU_VERSION-$MONGO_VERSION/bin" >> $GITHUB_PATH - mkdir $PWD/db - mongod --dbpath $PWD/db --logpath /dev/null --nojournal --fork - - - name: Run test - run: go test ./... -race - - # build binary without debug info to reduce its size - - name: build binary - run: go build -ldflags "-w -s" - - - name: Register SSH key - continue-on-error: true - uses: webfactory/ssh-agent@v0.9.0 - with: - ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY_PRODUCTION }} - - - name: Update known host - run: ssh-keyscan -H ${{ secrets.HOST_PRODUCTION }} > /home/runner/.ssh/known_hosts - - # stop the service, drop mongodb databases, and copy the new binary and upload the new binary - # before restarting the service, we need to allow binary to listen on protected - # port 80 & 443 with setcap - - name: Deploy on first node - run: | - ssh $APP_NAME@${{ secrets.HOST_PRODUCTION }} sudo systemctl stop $APP_NAME - ssh $APP_NAME@${{ secrets.HOST_PRODUCTION }} mv /home/$APP_NAME/$APP_NAME /home/$APP_NAME/${APP_NAME}_old || true - scp $APP_NAME $APP_NAME@${{ secrets.HOST_PRODUCTION }}:/home/$APP_NAME - ssh $APP_NAME@${{ secrets.HOST_PRODUCTION }} sudo setcap CAP_NET_BIND_SERVICE=+ep $APP_NAME - ssh $APP_NAME@${{ secrets.HOST_PRODUCTION }} sudo systemctl restart $APP_NAME - - # ping the server until we're sure it's UP - # script is an adaptation of this question: https://unix.stackexchange.com/questions/82598/ - - name: Check new instance has started correctly - id: ping_new_instance - run: for i in 10 10 15 15; do sleep $i; wget -nv --no-check-certificate -O- https://${{ secrets.HOST_PRODUCTION }}/health | grep -q '{"Status":"UP"' && s=0 && break || s=$?; done; (exit $s) - - - name: Check if home/view pages have changed - uses: tj-actions/verify-changed-files@v17 - id: verify-changed-files - with: - files: | - internal/web/playground.html - internal/web/static/about.html - internal/view.go - internal/home.go - - - name: If files changed, clear cloudflare cache - if: steps.verify-changed-files.outputs.files_changed == 'true' - run: | - wget -nv --no-check-certificate --header="Authorization: Bearer ${{ secrets.CLOUDFLARE_TOKEN }}" -O- https://${{ secrets.HOST_PRODUCTION }}/clear_cache - - - name: Print first logs if deploy failed - if: failure() && steps.ping_new_instance.outcome == 'failure' - run: ssh $APP_NAME@${{ secrets.HOST_PRODUCTION }} journalctl -u $APP_NAME | tail -n 600 | grep -v "Deleting db" - - - name: Rollback previous version if deploy failed - if: failure() && steps.ping_new_instance.outcome == 'failure' - run: | - ssh $APP_NAME@${{ secrets.HOST_PRODUCTION }} sudo systemctl stop $APP_NAME - ssh $APP_NAME@${{ secrets.HOST_PRODUCTION }} mv /home/$APP_NAME/${APP_NAME}_old /home/$APP_NAME/$APP_NAME || true - ssh $APP_NAME@${{ secrets.HOST_PRODUCTION }} sudo systemctl restart $APP_NAME \ No newline at end of file + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: "1.23" + + - name: Vet code + run: go vet ./... + + - name: Download MongoDB and setup standalone db + run: | + wget --quiet http://downloads.mongodb.org/linux/mongodb-$UBUNTU_VERSION-$MONGO_VERSION.tgz + tar xzvf mongodb-$UBUNTU_VERSION-$MONGO_VERSION.tgz + echo "$PWD/mongodb-$UBUNTU_VERSION-$MONGO_VERSION/bin" >> $GITHUB_PATH + mkdir $PWD/db + mongod --dbpath $PWD/db --logpath /dev/null --nojournal --fork + + - name: Run test + run: go test ./... -race + + # build binary without debug info to reduce its size + - name: build binary + run: go build -ldflags "-w -s" + + - name: Register SSH key + continue-on-error: true + uses: webfactory/ssh-agent@v0.9.0 + with: + ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY_PRODUCTION }} + + - name: Update known host + run: ssh-keyscan -H ${{ secrets.HOST_PRODUCTION }} > /home/runner/.ssh/known_hosts + + # stop the service, drop mongodb databases, and copy the new binary and upload the new binary + # before restarting the service, we need to allow binary to listen on protected + # port 80 & 443 with setcap + - name: Deploy on first node + run: | + ssh $APP_NAME@${{ secrets.HOST_PRODUCTION }} sudo systemctl stop $APP_NAME + ssh $APP_NAME@${{ secrets.HOST_PRODUCTION }} mv /home/$APP_NAME/$APP_NAME /home/$APP_NAME/${APP_NAME}_old || true + scp $APP_NAME $APP_NAME@${{ secrets.HOST_PRODUCTION }}:/home/$APP_NAME + ssh $APP_NAME@${{ secrets.HOST_PRODUCTION }} sudo setcap CAP_NET_BIND_SERVICE=+ep $APP_NAME + ssh $APP_NAME@${{ secrets.HOST_PRODUCTION }} sudo systemctl restart $APP_NAME + + # ping the server until we're sure it's UP + # script is an adaptation of this question: https://unix.stackexchange.com/questions/82598/ + - name: Check new instance has started correctly + id: ping_new_instance + run: for i in 10 10 15 15; do sleep $i; wget -nv --no-check-certificate -O- https://${{ secrets.HOST_PRODUCTION }}/health | grep -q '{"Status":"UP"' && s=0 && break || s=$?; done; (exit $s) + + - name: Check if home/view pages have changed + uses: tj-actions/verify-changed-files@v17 + id: verify-changed-files + with: + files: | + internal/web/playground.html + internal/web/static/about.html + internal/view.go + internal/home.go + + - name: If files changed, clear cloudflare cache + if: steps.verify-changed-files.outputs.files_changed == 'true' + run: | + wget -nv --no-check-certificate --header="Authorization: Bearer ${{ secrets.CLOUDFLARE_TOKEN }}" -O- https://${{ secrets.HOST_PRODUCTION }}/clear_cache + + - name: Print first logs if deploy failed + if: failure() && steps.ping_new_instance.outcome == 'failure' + run: ssh $APP_NAME@${{ secrets.HOST_PRODUCTION }} journalctl -u $APP_NAME | tail -n 600 | grep -v "Deleting db" + + - name: Rollback previous version if deploy failed + if: failure() && steps.ping_new_instance.outcome == 'failure' + run: | + ssh $APP_NAME@${{ secrets.HOST_PRODUCTION }} sudo systemctl stop $APP_NAME + ssh $APP_NAME@${{ secrets.HOST_PRODUCTION }} mv /home/$APP_NAME/${APP_NAME}_old /home/$APP_NAME/$APP_NAME || true + ssh $APP_NAME@${{ secrets.HOST_PRODUCTION }} sudo systemctl restart $APP_NAME diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c51777d..9db4b8d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: Run backend and e2e tests +name: Run backend and e2e tests on: push: @@ -8,7 +8,7 @@ on: branches-ignore: - production -env: +env: MONGO_VERSION: 8.0.3 UBUNTU_VERSION: linux-x86_64-ubuntu2004 @@ -17,61 +17,61 @@ jobs: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-go@v5 - with: - go-version: '1.23' - - - name: Lint code - uses: golangci/golangci-lint-action@v4 - with: - version: v1.57.2 - args: --timeout 2m0s - - - name: Vet code - run: go vet ./... - - - name: Download MongoDB and setup standalone db - run: | - wget --quiet http://downloads.mongodb.org/linux/mongodb-$UBUNTU_VERSION-$MONGO_VERSION.tgz - tar xzvf mongodb-$UBUNTU_VERSION-$MONGO_VERSION.tgz - echo "$PWD/mongodb-$UBUNTU_VERSION-$MONGO_VERSION/bin" >> $GITHUB_PATH - mkdir $PWD/db - mongod --dbpath $PWD/db --logpath /dev/null --nojournal --fork - - - name: Run test - run: tools/test.sh - - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4 - with: - files: coverage.txt - - - uses: actions/setup-node@v4 - with: - node-version: 20 - - - name: Install npm test dependencies - working-directory: internal/web - run: npm install - - - name: Check minified files - id: check_minified_files - working-directory: internal/web - run: | - npm run build - git diff --quiet - - - name: Print message if files are out of sync - if: failure() && steps.check_minified_files.outcome == 'failure' - run: echo "minified files are out of sync, run 'npm run build' and commit the modified files" - - - name: Start local instance - run: | - go build - ./mongoplayground& - - - name: Run e2e tests - working-directory: internal/web - run: npm run test + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version: "1.23" + + - name: Lint code + uses: golangci/golangci-lint-action@v4 + with: + version: v1.57.2 + args: --timeout 2m0s + + - name: Vet code + run: go vet ./... + + - name: Download MongoDB and setup standalone db + run: | + wget --quiet http://downloads.mongodb.org/linux/mongodb-$UBUNTU_VERSION-$MONGO_VERSION.tgz + tar xzvf mongodb-$UBUNTU_VERSION-$MONGO_VERSION.tgz + echo "$PWD/mongodb-$UBUNTU_VERSION-$MONGO_VERSION/bin" >> $GITHUB_PATH + mkdir $PWD/db + mongod --dbpath $PWD/db --logpath /dev/null --nojournal --fork + + - name: Run test + run: tools/test.sh + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v4 + with: + files: coverage.txt + + - uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Install npm test dependencies + working-directory: internal/web + run: npm install + + - name: Check minified files + id: check_minified_files + working-directory: internal/web + run: | + npm run build + git diff --quiet + + - name: Print message if files are out of sync + if: failure() && steps.check_minified_files.outcome == 'failure' + run: echo "minified files are out of sync, run 'npm run build' and commit the modified files" + + - name: Start local instance + run: | + go build + ./mongoplayground& + + - name: Run e2e tests + working-directory: internal/web + run: npm run test