diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 60517a61d..a8e60b1ef 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,2 +1,2 @@ # Set default code owners for all files in repo -* @benbcai @jmsv6d @elliott-hoffman-cerner +@cerner/terra-code-owners diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 280c62c16..ceb51e8ea 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,27 +1,51 @@ + + ### Summary - + + +**What was changed:** + + +**Why it was changed:** - - -Closes # -### Deployment Link - -https://terra-applic-.herokuapp.com/ ### Testing +This change was tested using: + +- [ ] WDIO +- [ ] Jest +- [ ] Visual testing (please attach a screenshot or recording) +- [ ] Other (please describe below) +- [ ] No tests are needed + +### Reviews + +In addition to engineering reviews, this PR needs: + +- [ ] UX review +- [ ] Accessibility review +- [ ] Functional review + ### Additional Details - +UXPLATFORM-XXXX + +--- Thank you for contributing to Terra. @cerner/terra diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml new file mode 100644 index 000000000..242b0143b --- /dev/null +++ b/.github/actions/setup/action.yml @@ -0,0 +1,15 @@ +name: Setup Project +description: Steps neccessary to setup the project +runs: + using: "composite" + steps: + - name: Setup Node 14.x + uses: actions/setup-node@v3 + with: + node-version: 14.x + - name: Clean Environment + shell: bash + run: npm run clean + - name: Install Dependencies + shell: bash + run: npm install diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml new file mode 100644 index 000000000..919bd30f3 --- /dev/null +++ b/.github/workflows/ci-cd.yml @@ -0,0 +1,116 @@ +--- +name: CI and CD + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + type: choice + options: + - info + - warning + - debug + tags: + description: 'Test scenario tags' + required: false + type: boolean + environment: + description: 'Environment to run tests against' + type: environment + required: true + push: + branches: ['terra-application-v1'] + pull_request: + branches: ['terra-application-v1'] + schedule: + - cron: '0 1 * * SUN' + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout Project + uses: actions/checkout@v3 + - name: Setup Project + uses: ./.github/actions/setup + - if: github.event_name == 'pull_request' + name: Danger + uses: danger/danger-js@9.1.8 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # https://github.com/danger/danger-js/issues/557#issuecomment-664851950 + DANGER_DISABLE_TRANSPILATION: true + - name: Linting Project + run: | + npm run lint + - name: Testing Project + run: | + npm run jest + wdio: + runs-on: ubuntu-latest + + strategy: + fail-fast: true + matrix: + theme: [default, lowlight, fusion] + + steps: + - name: Checkout Project + uses: actions/checkout@v3 + - name: Setup Project + uses: ./.github/actions/setup + - name: Compile Project Default + run: | + npm run compile:prod -- --output-path build/default + if: matrix.theme == 'default' + - name: Compile Project Lowlight + run: | + npm run compile:lowlight -- --output-path build/lowlight + if: matrix.theme == 'lowlight' + - name: Compile Project Fusion + run: | + npm run compile:fusion -- --output-path build/fusion + if: matrix.theme == 'fusion' + - name: Run WDIO Tests for theme ${{ matrix.theme }} + env: + SITE: build/${{ matrix.theme }} + run: npm run wdio-${{ matrix.theme }} + + release-and-deploy: + runs-on: ubuntu-latest + + needs: [build, wdio] + if: github.ref == 'refs/heads/terra-application-v1' + steps: + - name: Checkout Project + uses: actions/checkout@v2 + - name: Setup GitHub Config + run: | + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git config --global user.name "github-actions[bot]" + - name: Setup Project + uses: ./.github/actions/setup + - name: Build + env: + TERRA_DEV_SITE_NEW_RELIC_LICENSE_KEY: ${{ secrets.TERRA_DEV_SITE_NEW_RELIC_LICENSE_KEY }} + TERRA_DEV_SITE_NEW_RELIC_APPLICATION_ID: "141260567" + TERRA_DEV_SITE_PUBLIC_PATH: /terra-application/ + run: npm run compile:prod + - name: Release + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: npx terra release + # - name: Deploy + # uses: peaceiris/actions-gh-pages@v3 + # with: + # github_token: ${{ secrets.GITHUB_TOKEN }} + # publish_dir: ./build + # keep_files: true + # user_name: 'github-actions[bot]' + # user_email: 'github-actions[bot]@users.noreply.github.com' + # commit_message: 'chore(docs): Regenerate docs' diff --git a/.github/workflows/pr-close.yml b/.github/workflows/pr-close.yml new file mode 100644 index 000000000..38495ceb6 --- /dev/null +++ b/.github/workflows/pr-close.yml @@ -0,0 +1,46 @@ +name: delete preview on PR close + +# only trigger on pull request closed events +on: + pull_request: + types: [closed] + +jobs: + delete_preview: + runs-on: ubuntu-latest + env: + PR_PATH: pull/${{github.event.number}} + ENVIRONMENT_NAME: preview-pr-${{ github.event.number }} + steps: + - name: make empty dir + run: mkdir public + + - name: delete folder + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./public + destination_dir: ${{ env.PR_PATH }} + + - name: get deployment + id: get-deplpoyment + uses: octokit/request-action@v2.x + with: + route: GET /repos/{repository}/deployments + repository: ${{ github.repository }} + ref: ${{ github.event.pull_request.head.ref }} + env: + GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' + + - name: set previous deployment as inactive + if: | + steps.get-deplpoyment.outputs.status != '404' && + toJSON(fromJSON(steps.get-deplpoyment.outputs.data)) != '[]' + uses: octokit/request-action@v2.x + with: + route: POST /repos/{repository}/deployments/{deployment}/statuses + deployment: ${{ fromJSON(steps.get-deplpoyment.outputs.data)[0].id }} + repository: ${{ github.repository }} + state: inactive + env: + GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' diff --git a/.github/workflows/pr-preview.yml b/.github/workflows/pr-preview.yml new file mode 100644 index 000000000..07c3048f3 --- /dev/null +++ b/.github/workflows/pr-preview.yml @@ -0,0 +1,128 @@ +name: pr-preview + +on: + pull_request: + branches: ['terra-application-v1'] +jobs: + deploy: + runs-on: ubuntu-latest + env: + PR_PATH: pull/${{ github.event.number }} + TERRA_DEV_SITE_PUBLIC_PATH: "/terra-application/pull/${{ github.event.number }}/" + BASE_URL: "https://engineering.cerner.com/${{ github.event.repository.name }}/pull/${{ github.event.number }}/" + ENVIRONMENT_NAME: preview-pr-${{ github.event.number }} + steps: + - name: check for previous deployment + id: check-previous + uses: octokit/request-action@v2.x + with: + route: GET /repos/{repository}/deployments + repository: ${{ github.repository }} + ref: ${{ github.event.pull_request.head.ref }} + env: + GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' + + - name: set previous deployment as inactive + if: | + steps.check-previous.outputs.status != '404' && + toJSON(fromJSON(steps.check-previous.outputs.data)) != '[]' + uses: octokit/request-action@v2.x + with: + route: POST /repos/{repository}/deployments/{deployment}/statuses + repository: ${{ github.repository }} + deployment: ${{ fromJSON(steps.check-previous.outputs.data)[0].id }} + log_url: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} + state: inactive + env: + GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' + + - name: get pull request + id: get-pull-request + uses: octokit/request-action@v2.x + with: + route: GET /repos/{repository}/pulls/{issue_id} + repository: ${{ github.repository }} + issue_id: ${{ github.event.number }} + env: + GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' + + - name: create deployment + id: create-deployment + uses: octokit/request-action@v2.x + if: | + steps.check-previous.outputs.status != '404' + env: + GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' + with: + route: POST /repos/{repository}/deployments + repository: ${{ github.repository }} + ref: ${{ github.event.pull_request.head.ref }} + transient_environment: true + auto_merge: false + environment: ${{env.ENVIRONMENT_NAME}} + required_contexts: '[]' + + - name: set deployment status to in progress + id: start_deployment + uses: octokit/request-action@v2.x + if: | + steps.check-previous.outputs.status != '404' + with: + route: POST /repos/{repository}/deployments/{deployment}/statuses + repository: ${{ github.repository }} + deployment: ${{ fromJSON(steps.create-deployment.outputs.data).id }} + environment: ${{ env.ENVIRONMENT_NAME }} + environment_url: ${{ env.BASE_URL }} + log_url: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} + state: in_progress + env: + GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' + + - uses: actions/checkout@v3 + with: + ref: ${{ fromJSON(steps.get-pull-request.outputs.data).head.sha }} + + - name: setup project + uses: ./.github/actions/setup + + - name: build project + env: + TERRA_DEV_SITE_NEW_RELIC_LICENSE_KEY: ${{ secrets.TERRA_DEV_SITE_NEW_RELIC_LICENSE_KEY }} + TERRA_DEV_SITE_NEW_RELIC_APPLICATION_ID: "144458769" + run: npm run compile:prod + + - name: deploy the pull request + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./build + destination_dir: ${{ env.PR_PATH }} + + - name: set deployment status to success + id: successful_deployment + uses: octokit/request-action@v2.x + with: + route: POST /repos/{repository}/deployments/{deployment}/statuses + repository: ${{ github.repository }} + deployment: ${{ fromJson(steps.create-deployment.outputs.data).id }} + environment: ${{ env.ENVIRONMENT_NAME }} + environment_url: ${{ env.BASE_URL }} + log_url: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} + state: success + env: + GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' + + - name: set deployment status to failure + id: failed_deployment + uses: octokit/request-action@v2.x + if: failure() + with: + route: POST /repos/{repository}/deployments/{deployment}/statuses + repository: ${{ github.repository }} + deployment: ${{ fromJson(steps.create-deployment.outputs.data).id }} + environment: ${{ env.ENVIRONMENT_NAME }} + environment_url: ${{ env.BASE_URL }} + log_url: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} + state: failure + env: + GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 258ec3ce7..000000000 --- a/.travis.yml +++ /dev/null @@ -1,77 +0,0 @@ -language: node_js -sudo: required -services: - - docker -branches: - only: - - main - - application-v1-53 -cache: - directories: - - travis-build - - docker_images -before_install: - # Clean install on any new build - - npm run clean -before_script: - # Load Docker Cache - - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin - - docker load -i docker_images/images.tar || true -jobs: - include: - - stage: danger lint jest and compile - script: - # clear the cache of any old build artifacts - - rm -rf ./travis-build - - npm run danger - - npm run lint - - npm run jest - # These can't be built in parallel because the cache is a single object and you can't add to it in parallel - - npm run compile:prod -- --output-path $TRAVIS_BUILD_DIR/travis-build/default - - npm run compile:lowlight -- --output-path $TRAVIS_BUILD_DIR/travis-build/lowlight - - npm run compile:fusion -- --output-path $TRAVIS_BUILD_DIR/travis-build/fusion - # Prime the docker cache - - docker-compose --file ./node_modules/@cerner/terra-functional-testing/lib/docker/docker-compose.yml pull - # Save docker cache - - docker save -o docker_images/images.tar $(docker images -a -q) - # Split out all the wdio runs to not eat up all the travis executors at once. - - - stage: wdio - name: default-theme - # Don't clean install - before_install: skip - # Rely on the cache for node_modules.. this won't work for any node modules in the packages dir but works for running wdio - install: skip - script: - # using the travis env section to set env variables seems to break cache - - SITE=$TRAVIS_BUILD_DIR/travis-build/default npm run wdio-default - - name: lowlight-theme - before_install: skip - install: skip - script: - - SITE=$TRAVIS_BUILD_DIR/travis-build/lowlight npm run wdio-lowlight - - name: fusion-theme - before_install: skip - install: skip - script: - - SITE=$TRAVIS_BUILD_DIR/travis-build/fusion npm run wdio-fusion - - - stage: deploy - script: - - rm -rf ./travis-build - - npx terra release - before_deploy: - # Build again for deployment because we need the Public path to be updated. - - TERRA_DEV_SITE_NEW_RELIC_LICENSE_KEY='c494ac44c8' TERRA_DEV_SITE_NEW_RELIC_APPLICATION_ID='141260567' TERRA_DEV_SITE_PUBLIC_PATH='/terra-application/' npm run compile:prod - deploy: - provider: pages - skip_cleanup: true - github_token: $GITHUB_TOKEN # Set in travis-ci.com dashboard - local_dir: $TRAVIS_BUILD_DIR/build - on: - branch: application-v1-53 -stages: - - danger lint jest and compile - - wdio - - name: deploy - if: type != pull_request diff --git a/dangerfile.js b/dangerfile.js index e447472ea..b72a99c82 100644 --- a/dangerfile.js +++ b/dangerfile.js @@ -12,6 +12,7 @@ if (lernaConfig.command) { const CHANGELOG_PATTERN = /^packages\/([a-z-])*\/CHANGELOG\.md/i; const changedFiles = danger.git.created_files.concat(danger.git.modified_files); +const allowedFilepaths = ['package.json', 'CHANGELOG.md', 'src', 'translations', 'terra-application-docs']; const changedChangelogs = new Set(); const changedPackages = new Set(); @@ -33,16 +34,24 @@ changedFiles.forEach((file) => { return; } + if (!allowedFilepaths.some(filepath => file.includes(filepath))) { + // skip further processing if the changed file is not among the allowed filepaths + return; + } + if (CHANGELOG_PATTERN.test(file)) { + // changed file is the CHANGELOG itself changedChangelogs.add(packageName); - } else { // file is in a package and was changed - we need a changelog - changedPackages.add(packageName); + return; } + + // for other allowed files + changedPackages.add(packageName); }); const missingChangelogs = [...changedPackages].filter(packageName => !changedChangelogs.has(packageName)); // Fail if there are package changes without a CHANGELOG update if (missingChangelogs.length > 0) { - fail(`Please include a CHANGELOG entry for each changed package on this PR. Looks like a CHANGELOG is missing for: \n\n - ${missingChangelogs.join('\n - ')}`); + fail(`Please include a CHANGELOG entry for each changed package on this PR. Looks like a CHANGELOG entry is missing for: \n\n - ${missingChangelogs.join('\n - ')}`); } diff --git a/package.json b/package.json index 280276acf..6b0e85a65 100644 --- a/package.json +++ b/package.json @@ -52,12 +52,13 @@ }, "scripts": { "bootstrap:hoist": "lerna bootstrap --hoist", - "clean": "lerna clean --yes && rm -rf node_modules || true", - "clean:install": "npm run clean && npm install", + "clean": "npm run clean:root && npm run clean:lib", + "clean:install": "npm run clean && time npm install", + "clean:lib": "rm -rf packages/**/lib", + "clean:root": "$(lerna clean --yes || true) && echo 'removing ./node_modules' && rm -rf node_modules && echo 'removed ./node_modules'", "clean:obsolete-snapshots": "npm test -- -u", - "compile": "npm run compile:clean && npm run compile:build", + "compile": "npm run clean:lib && npm run compile:build", "compile:build": "lerna ls -a | sed 's/@cerner\\///g' | cut -d ' ' -f1 | xargs -I {} babel packages/{}/src --out-dir packages/{}/lib --copy-files", - "compile:clean": "rm -rf packages/**/lib", "compile:src": "lerna run compile", "compile:prod": "rm -rf ./build; NODE_ENV=production webpack --mode=production", "compile:lowlight": "rm -rf ./build; THEME=clinical-lowlight-theme webpack --mode=production", @@ -68,7 +69,8 @@ "jest": "jest", "jest:coverage": "jest --coverage", "lint": "npm run lint:js && npm run lint:scss && npm run lint:package-json", - "lint:js": "eslint --ext .js,.jsx .", + "lint:js": "eslint --ext .js,.jsx . --max-warnings 0", + "lint:js:fix": "eslint --fix --ext .js,.jsx .", "lint:scss": "stylelint 'packages/**/src/**/*.scss' --syntax scss", "lint:package-json": "terra package-json-lint", "prepare-for-release": "terra prepare-for-release",