From 30345269f33f901564da97a69df0db4f7ed3c336 Mon Sep 17 00:00:00 2001 From: tangoyankee Date: Wed, 11 Sep 2024 14:25:48 -0400 Subject: [PATCH] Configure gh action deployments from main - Implement client code quality checks on pull requests and pulls onto main - Implement deployments to client and server environments of qa, staging, and production - Make deployments depend on successful code quality checks - Modify msal environment variable check to specify which variable is missing closes #1520 --- .github/workflows/main.yml | 30 ------- .github/workflows/production.yml | 112 +++++++++++++++++++++++++++ .github/workflows/qa.yml | 106 +++++++++++++++++++++++++ .github/workflows/staging.yml | 112 +++++++++++++++++++++++++++ netlify.toml | 19 ----- server/src/provider/msal.provider.ts | 13 ++-- 6 files changed, 335 insertions(+), 57 deletions(-) delete mode 100644 .github/workflows/main.yml create mode 100644 .github/workflows/production.yml create mode 100644 .github/workflows/qa.yml create mode 100644 .github/workflows/staging.yml delete mode 100644 netlify.toml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 991ac1641..000000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Build - -on: - push: - branches: - - master - - develop - pull_request: - -jobs: - test: - name: Tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 - with: - node-version: 12.x - - name: install dependencies - run: yarn install --frozen-lockfile --non-interactive - working-directory: client - - name: build - env: - DISABLE_SOURCE_MAPS: true - BROCCOLI_ENV: production - run: yarn ember build -prod - working-directory: client - - name: test - run: yarn test - working-directory: client diff --git a/.github/workflows/production.yml b/.github/workflows/production.yml new file mode 100644 index 000000000..e7242acd4 --- /dev/null +++ b/.github/workflows/production.yml @@ -0,0 +1,112 @@ +name: ๐ŸŒ  Deploy api to production + +on: workflow_dispatch + +jobs: + test-client: + name: ๐Ÿงช Test client code + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + sparse-checkout: client + - uses: actions/setup-node@v1 + with: + node-version: 14.x + - name: install dependencies + run: yarn install --frozen-lockfile --non-interactive + working-directory: client + - name: build + env: + DISABLE_SOURCE_MAPS: true + BROCCOLI_ENV: production + run: yarn ember build -prod + working-directory: client + - name: test + run: yarn test + working-directory: client + deploy-server: + name: ๐Ÿš€ Deploy server + needs: test-client + environment: + name: production + url: https://zap-api.nycplanningdigital.com + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + sparse-checkout: server + - uses: akhileshns/heroku-deploy@v3.13.15 + name: Deploy server to Heroku + with: + heroku_email: ${{secrets.HEROKU_EMAIL}} + heroku_api_key: ${{secrets.HEROKU_API_KEY}} + heroku_app_name: ${{ vars.HEROKU_APP_NAME }} + team: ${{secrets.HEROKU_TEAM}} + appdir: server + env: + HD_ADO_PRINCIPAL: ${{secrets.ADO_PRINCIPAL}} + HD_AIRTABLE_API_KEY: ${{ secrets.AIRTABLE_API_KEY }} + HD_AUTHORITY_HOST_URL: ${{secrets.AUTHORITY_HOST_URL}} + HD_CLIENT_ID: ${{secrets.CLIENT_ID}} + HD_CLIENT_SECRET: ${{secrets.CLIENT_SECRET}} + HD_CRM_ADMIN_SERVICE_USER: ${{secrets.CRM_ADMIN_SERVICE_USER}} + HD_CRM_HOST: ${{secrets.CRM_HOST}} + HD_CRM_SIGNING_SECRET: ${{secrets.CRM_SIGNING_SECRET}} + HD_CRM_URL_PATH: ${{secrets.CRM_URL_PATH}} + HD_GITHUB_ACCESS_TOKEN: ${{secrets.FEEDBACK_GITHUB_ACCESS_TOKEN}} + HD_NEW_RELIC_LICENSE_KEY: ${{ secrets.NEW_RELIC_LICENSE_KEY }} + HD_NEW_RELIC_LOG: ${{ secrets.NEW_RELIC_LOG }} + HD_NODE_ENV: ${{ vars.NODE_ENV }} + HD_NPM_CONFIG_PRODUCTION: ${{ vars.NPM_CONFIG_PRODUCTION }} + HD_NYCID_CONSOLE_PASSWORD: ${{secrets.NYCID_CONSOLE_PASSWORD}} + HD_PAPERTRAIL_API_TOKEN: ${{ secrets.PAPERTRAIL_API_TOKEN }} + HD_RECAPTCHA_SECRET_KEY: ${{secrets.RECAPTCHA_SECRET_KEY}} + HD_RECAPTCHA_SITE_KEY: ${{secrets.RECAPTCHA_SITE_KEY}} + HD_SHAREPOINT_CLIENT_ID: ${{secrets.SHAREPOINT_CLIENT_ID}} + HD_SHAREPOINT_CLIENT_SECRET: ${{secrets.SHAREPOINT_CLIENT_SECRET}} + HD_SHAREPOINT_CRM_SITE: ${{secrets.SHAREPOINT_CRM_SITE}} + HD_SHAREPOINT_SITE_ID: ${{secrets.SHAREPOINT_SITE_ID}} + HD_SHAREPOINT_TARGET_HOST: ${{secrets.SHAREPOINT_TARGET_HOST}} + HD_SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + HD_TENANT_ID: ${{secrets.TENANT_ID}} + HD_TOKEN_PATH: ${{secrets.TOKEN_PATH}} + HD_USER_API_KEY: ${{ secrets.USER_API_KEY }} + deploy-client: + name: ๐Ÿ›ซ Deploy client + needs: [test-client, deploy-server] + environment: + name: production + url: https://zap.planninglabs.nyc + runs-on: ubuntu-latest + env: + HOST: ${{ vars.ZAP_API_HOST }} + NYCID_CLIENT_ID: ${{ vars.NYCID_CLIENT_ID }} + NYC_ID_HOST: ${{ vars.NYC_ID_HOST }} + MAINTENANCE_START: ${{ vars.MAINTENANCE_START }} + MAINTENANCE_END: ${{ vars.MAINTENANCE_END }} + steps: + - uses: actions/checkout@v4 + with: + sparse-checkout: client + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: 14.x + - name: Install application dependencies + working-directory: client + run: yarn install --immutable --immutable-cache --check-cache + - name: Build client + working-directory: client + run: yarn run build --environment=production + - name: Install netlify + # Use npm over yarn because yarn was not respecting the exact version of a dependency + run: npm i -g netlify-cli@15.11.0 + - name: Deploy client to Netlify + run: | + netlify deploy \ + --dir client/dist \ + --site ${{secrets.NETLIFY_SITE_ID}} \ + --auth ${{secrets.NETLIFY_AUTH_TOKEN}} \ + --message "${{ github.event.head_commit.message }}" + --prod \ No newline at end of file diff --git a/.github/workflows/qa.yml b/.github/workflows/qa.yml new file mode 100644 index 000000000..b61d5cf18 --- /dev/null +++ b/.github/workflows/qa.yml @@ -0,0 +1,106 @@ +name: ๐Ÿ•ต๏ธ Deploy to quality assurance + +on: workflow_dispatch + +jobs: + test-client: + name: ๐Ÿงช Test client code + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + sparse-checkout: client + - uses: actions/setup-node@v1 + with: + node-version: 14.x + - name: install dependencies + run: yarn install --frozen-lockfile --non-interactive + working-directory: client + - name: build + env: + DISABLE_SOURCE_MAPS: true + BROCCOLI_ENV: production + run: yarn ember build -prod + working-directory: client + - name: test + run: yarn test + working-directory: client + deploy-server: + name: ๐Ÿš€ Deploy server + needs: test-client + environment: + name: qa + url: https://qa-zap-api.nycplanningdigital.com + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + sparse-checkout: server + - uses: akhileshns/heroku-deploy@v3.13.15 + name: Deploy server to Heroku + with: + heroku_email: ${{secrets.HEROKU_EMAIL}} + heroku_api_key: ${{secrets.HEROKU_API_KEY}} + heroku_app_name: ${{ vars.HEROKU_APP_NAME }} + team: ${{secrets.HEROKU_TEAM}} + appdir: server + env: + HD_ADO_PRINCIPAL: ${{secrets.ADO_PRINCIPAL}} + HD_AIRTABLE_API_KEY: ${{ secrets.AIRTABLE_API_KEY }} + HD_AUTHORITY_HOST_URL: ${{secrets.AUTHORITY_HOST_URL}} + HD_CLIENT_ID: ${{secrets.CLIENT_ID}} + HD_CLIENT_SECRET: ${{secrets.CLIENT_SECRET}} + HD_CRM_ADMIN_SERVICE_USER: ${{secrets.CRM_ADMIN_SERVICE_USER}} + HD_CRM_HOST: ${{secrets.CRM_HOST}} + HD_CRM_SIGNING_SECRET: ${{secrets.CRM_SIGNING_SECRET}} + HD_CRM_URL_PATH: ${{secrets.CRM_URL_PATH}} + HD_NYCID_CONSOLE_PASSWORD: ${{secrets.NYCID_CONSOLE_PASSWORD}} + HD_PAPERTRAIL_API_TOKEN: ${{ secrets.PAPERTRAIL_API_TOKEN }} + HD_RECAPTCHA_SECRET_KEY: ${{secrets.RECAPTCHA_SECRET_KEY}} + HD_RECAPTCHA_SITE_KEY: ${{secrets.RECAPTCHA_SITE_KEY}} + HD_SHAREPOINT_CLIENT_ID: ${{secrets.SHAREPOINT_CLIENT_ID}} + HD_SHAREPOINT_CLIENT_SECRET: ${{secrets.SHAREPOINT_CLIENT_SECRET}} + HD_SHAREPOINT_CRM_SITE: ${{secrets.SHAREPOINT_CRM_SITE}} + HD_SHAREPOINT_SITE_ID: ${{secrets.SHAREPOINT_SITE_ID}} + HD_SHAREPOINT_TARGET_HOST: ${{secrets.SHAREPOINT_TARGET_HOST}} + HD_SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + HD_TENANT_ID: ${{secrets.TENANT_ID}} + HD_TOKEN_PATH: ${{secrets.TOKEN_PATH}} + deploy-client: + name: ๐Ÿ›ซ Deploy client + needs: [test-client, deploy-server] + environment: + name: staging + url: https://staging--labs-zap.netlify.app + runs-on: ubuntu-latest + env: + HOST: ${{ vars.ZAP_API_HOST }} + NYCID_CLIENT_ID: ${{ vars.NYCID_CLIENT_ID }} + NYC_ID_HOST: ${{ vars.NYC_ID_HOST }} + MAINTENANCE_START: ${{ vars.MAINTENANCE_START }} + MAINTENANCE_END: ${{ vars.MAINTENANCE_END }} + steps: + - uses: actions/checkout@v4 + with: + sparse-checkout: client + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: 14.x + - name: Install application dependencies + working-directory: client + run: yarn install --immutable --immutable-cache --check-cache + - name: Build client + working-directory: client + run: yarn run build --environment=production + - name: Install netlify + # Use npm over yarn because yarn was not respecting the exact version of a dependency + run: npm i -g netlify-cli@15.11.0 + - name: Deploy client to Netlify + run: | + netlify deploy \ + --dir client/dist \ + --alias ${{github.ref_name}}_${{github.sha}} \ + --site ${{secrets.NETLIFY_SITE_ID}} \ + --auth ${{secrets.NETLIFY_AUTH_TOKEN}} \ + --message "${{ github.event.head_commit.message }}" diff --git a/.github/workflows/staging.yml b/.github/workflows/staging.yml new file mode 100644 index 000000000..899920b85 --- /dev/null +++ b/.github/workflows/staging.yml @@ -0,0 +1,112 @@ +name: ๐ŸŽญ Deploy to staging + +on: + push: + branches: + - main + +jobs: + test-client: + name: ๐Ÿงช Test client code + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + sparse-checkout: client + - uses: actions/setup-node@v1 + with: + node-version: 14.x + - name: install dependencies + run: yarn install --frozen-lockfile --non-interactive + working-directory: client + - name: build + env: + DISABLE_SOURCE_MAPS: true + BROCCOLI_ENV: production + run: yarn ember build -prod + working-directory: client + - name: test + run: yarn test + working-directory: client + deploy-server: + name: ๐Ÿš€ Deploy server + needs: test-client + environment: + name: staging + url: https://staging-zap-api.nycplanningdigital.com + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + ref: 'main' + sparse-checkout: server + - uses: akhileshns/heroku-deploy@v3.13.15 + name: Deploy server to Heroku + with: + heroku_email: ${{secrets.HEROKU_EMAIL}} + heroku_api_key: ${{secrets.HEROKU_API_KEY}} + heroku_app_name: ${{ vars.HEROKU_APP_NAME }} + team: ${{secrets.HEROKU_TEAM}} + appdir: server + env: + HD_ADO_PRINCIPAL: ${{secrets.ADO_PRINCIPAL}} + HD_AIRTABLE_API_KEY: ${{ secrets.AIRTABLE_API_KEY }} + HD_AUTHORITY_HOST_URL: ${{secrets.AUTHORITY_HOST_URL}} + HD_CLIENT_ID: ${{secrets.CLIENT_ID}} + HD_CLIENT_SECRET: ${{secrets.CLIENT_SECRET}} + HD_CRM_ADMIN_SERVICE_USER: ${{secrets.CRM_ADMIN_SERVICE_USER}} + HD_CRM_HOST: ${{secrets.CRM_HOST}} + HD_CRM_SIGNING_SECRET: ${{secrets.CRM_SIGNING_SECRET}} + HD_CRM_URL_PATH: ${{secrets.CRM_URL_PATH}} + HD_NYCID_CONSOLE_PASSWORD: ${{secrets.NYCID_CONSOLE_PASSWORD}} + HD_PAPERTRAIL_API_TOKEN: ${{ secrets.PAPERTRAIL_API_TOKEN }} + HD_RECAPTCHA_SECRET_KEY: ${{secrets.RECAPTCHA_SECRET_KEY}} + HD_RECAPTCHA_SITE_KEY: ${{secrets.RECAPTCHA_SITE_KEY}} + HD_SHAREPOINT_CLIENT_ID: ${{secrets.SHAREPOINT_CLIENT_ID}} + HD_SHAREPOINT_CLIENT_SECRET: ${{secrets.SHAREPOINT_CLIENT_SECRET}} + HD_SHAREPOINT_CRM_SITE: ${{secrets.SHAREPOINT_CRM_SITE}} + HD_SHAREPOINT_SITE_ID: ${{secrets.SHAREPOINT_SITE_ID}} + HD_SHAREPOINT_TARGET_HOST: ${{secrets.SHAREPOINT_TARGET_HOST}} + HD_SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + HD_TENANT_ID: ${{secrets.TENANT_ID}} + HD_TOKEN_PATH: ${{secrets.TOKEN_PATH}} + deploy-client: + name: ๐Ÿ›ซ Deploy client + needs: [test-client, deploy-server] + environment: + name: staging + url: https://staging--labs-zap.netlify.app + runs-on: ubuntu-latest + env: + HOST: ${{ vars.ZAP_API_HOST }} + NYCID_CLIENT_ID: ${{ vars.NYCID_CLIENT_ID}} + NYC_ID_HOST: ${{ vars.NYC_ID_HOST}} + MAINTENANCE_START: ${{ vars.MAINTENANCE_START }} + MAINTENANCE_END: ${{ vars.MAINTENANCE_END }} + steps: + - uses: actions/checkout@v4 + with: + ref: 'main' + sparse-checkout: client + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: 14.x + - name: Install application dependencies + working-directory: client + run: yarn install --immutable --immutable-cache --check-cache + - name: Build client + working-directory: client + run: yarn run build --environment=production + - name: Install netlify + # Use npm over yarn because yarn was not respecting the exact version of a dependency + run: npm i -g netlify-cli@15.11.0 + - name: Deploy client to Netlify + run: | + netlify deploy \ + --dir client/dist \ + --alias staging \ + --site ${{secrets.NETLIFY_SITE_ID}} \ + --auth ${{secrets.NETLIFY_AUTH_TOKEN}} \ + --message "${{ github.event.head_commit.message }}" + diff --git a/netlify.toml b/netlify.toml deleted file mode 100644 index a7255f140..000000000 --- a/netlify.toml +++ /dev/null @@ -1,19 +0,0 @@ -[build] - base = "client/" - publish = "dist/" - command = "yarn build --environment=production" - ignore = "false" - -[context.develop] - environment = { HOST="https://zap-api-staging.herokuapp.com", NYCID_CLIENT_ID="lup-portal-staging", NYC_ID_HOST="https://accounts-nonprd.nyc.gov/account", MAINTENANCE_START='06/01/22 15:00', MAINTENANCE_END='06/01/22 16:00' } - -[context.master] - environment = { HOST="https://zap-api-production.herokuapp.com", NYCID_CLIENT_ID="lup-portal-production", NYC_ID_HOST="https://www1.nyc.gov/account", MAINTENANCE_START='06/01/22 15:00', MAINTENANCE_END='06/01/22 16:00' } - -# qa team -[context.qa] - environment = { HOST="https://zap-api-staging.herokuapp.com", NYCID_CLIENT_ID="lup-portal-staging", NYC_ID_HOST="https://accounts-nonprd.nyc.gov/account", MAINTENANCE_START='06/01/22 15:00', MAINTENANCE_END='06/01/22 16:00' } - -# deploy-preview -[context.deploy-preview] - environment = { HOST="https://zap-api-staging.herokuapp.com", NYCID_CLIENT_ID="lup-portal-staging", NYC_ID_HOST="https://accounts-nonprd.nyc.gov/account", MAINTENANCE_START='06/01/22 15:00', MAINTENANCE_END='06/01/22 16:00' } diff --git a/server/src/provider/msal.provider.ts b/server/src/provider/msal.provider.ts index b71352064..303ed1b5f 100644 --- a/server/src/provider/msal.provider.ts +++ b/server/src/provider/msal.provider.ts @@ -17,14 +17,11 @@ export const MsalProvider: FactoryProvider = { "SHAREPOINT_CLIENT_SECRET" ); const siteId: string | undefined = config.get("SHAREPOINT_SITE_ID"); - if ( - tenantId === undefined || - clientId === undefined || - clientSecret === undefined || - siteId === undefined - ) { - throw new Error("Missing SharePoint credential"); - } + + if(tenantId === undefined) throw new Error("Missing tenant id"); + if(clientId === undefined) throw new Error("Missing sharepoint client id"); + if(clientSecret === undefined) throw new Error("Missing sharepoint client secret"); + if(siteId === undefined) throw new Error("Missing sharepoint site id"); const cca = new msal.ConfidentialClientApplication({ auth: {