diff --git a/.github/workflows/main.yml b/.github/workflows/code_quality.yml similarity index 71% rename from .github/workflows/main.yml rename to .github/workflows/code_quality.yml index 991ac1641..da06bb7fc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/code_quality.yml @@ -1,21 +1,22 @@ -name: Build +name: ๐Ÿšง Run code quality checks on: push: branches: - - master - - develop + - main pull_request: jobs: - test: - name: Tests + test-client: + name: ๐Ÿงช Test client code runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 + with: + sparse-checkout: client - uses: actions/setup-node@v1 with: - node-version: 12.x + node-version: 14.x - name: install dependencies run: yarn install --frozen-lockfile --non-interactive working-directory: client diff --git a/.github/workflows/production.yml b/.github/workflows/production.yml new file mode 100644 index 000000000..c7ee36716 --- /dev/null +++ b/.github/workflows/production.yml @@ -0,0 +1,89 @@ +name: ๐ŸŒ  Deploy api to production + +on: workflow_dispatch + +jobs: + deploy-server: + name: ๐Ÿš€ Deploy server + 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: 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..752f8c77c --- /dev/null +++ b/.github/workflows/qa.yml @@ -0,0 +1,83 @@ +name: ๐Ÿ•ต๏ธ Deploy to quality assurance + +on: workflow_dispatch + +jobs: + deploy-server: + name: ๐Ÿš€ Deploy server + 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: 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..982496b52 --- /dev/null +++ b/.github/workflows/staging.yml @@ -0,0 +1,89 @@ +name: ๐ŸŽญ Deploy to staging + +on: + push: + branches: + - main + +jobs: + deploy-server: + name: ๐Ÿš€ Deploy server + 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: 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: {