diff --git a/.circleci/config.yml b/.circleci/config.yml index 29c9b03857..edc0f906dc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -11,6 +11,9 @@ dependencies: cache_directories: - ~/.cache/yarn +orbs: + nx: nrwl/nx@1.0.0 + executors: linux: working_directory: *working_directory @@ -126,27 +129,24 @@ jobs: - run: name: Check Package dependencies command: yarn depcheck - - run: - name: Get Last Sucessful Workflow Run - command: | - source ./scripts/circleci/get-successful-run.sh << pipeline.project.type >> $CIRCLE_PROJECT_USERNAME $CIRCLE_PROJECT_REPONAME $CIRCLE_BRANCH master false - echo "export BASE_SHA=\"$BASE_SHA\";" >> $BASH_ENV + - nx/set-shas: + main-branch-name: 'master' - run: name: Run Builds command: | - npx nx affected --target=build --base=$BASE_SHA --parallel --max-parallel=3 + npx nx affected --target=build --base=$NX_BASE --parallel --max-parallel=3 - run: name: Run Unit Tests command: | - npx nx affected --target=test --base=$BASE_SHA --parallel --max-parallel=2 + npx nx affected --target=test --base=$NX_BASE --parallel --max-parallel=2 - run: name: Run Linting command: | - npx nx affected --target=lint --base=$BASE_SHA --parallel --max-parallel=4 + npx nx affected --target=lint --base=$NX_BASE --parallel --max-parallel=4 - run: name: Run E2E Tests command: | - npx nx affected --target=e2e --base=$BASE_SHA + npx nx affected --target=e2e --base=$NX_BASE no_output_timeout: 45m - run: name: Stop All Running Agents for This CI Run @@ -171,23 +171,20 @@ jobs: steps: - setup: os: << parameters.os >> - - run: - name: Get Last Sucessful Workflow Run - command: | - source ./scripts/circleci/get-successful-run.sh << pipeline.project.type >> $CIRCLE_PROJECT_USERNAME $CIRCLE_PROJECT_REPONAME $CIRCLE_BRANCH master false - echo "export BASE_SHA=\"$BASE_SHA\";" >> $BASH_ENV + - nx/set-shas: + main-branch-name: 'master' - run: name: Run Builds - command: npx nx affected --target=build --base=$BASE_SHA --parallel --max-parallel=3 + command: npx nx affected --target=build --base=$NX_BASE --parallel --max-parallel=3 - run: name: Run Unit Tests - command: npx nx affected --target=test --base=$BASE_SHA --parallel --max-parallel=2 + command: npx nx affected --target=test --base=$NX_BASE --parallel --max-parallel=2 - run: name: Run Linting - command: npx nx affected --target=lint --base=$BASE_SHA --parallel --max-parallel=4 + command: npx nx affected --target=lint --base=$NX_BASE --parallel --max-parallel=4 - run: name: Run E2E Tests - command: npx nx affected --target=e2e --base=$BASE_SHA + command: npx nx affected --target=e2e --base=$NX_BASE no_output_timeout: 45m - run: name: Stop All Running Agents for This CI Run diff --git a/scripts/circleci/find-successful-workflow.js b/scripts/circleci/find-successful-workflow.js deleted file mode 100644 index 8d52e65710..0000000000 --- a/scripts/circleci/find-successful-workflow.js +++ /dev/null @@ -1,115 +0,0 @@ -#!/usr/bin/env node -const { execSync } = require('child_process'); -const https = require('https'); - -// first two argument params are node and script -const INPUTS_MAIN_BRANCH_NAME = process.argv[2]; -const PROJECT_SLUG = process.argv[3]; -const URL = `https://circleci.com/api/v2/project/${PROJECT_SLUG}/pipeline?branch=${INPUTS_MAIN_BRANCH_NAME}`; - -/** - * Main - * Cycle through pipelines until first successful run is found - * or we reach the end of the pipeline history - * - * If found, log it to the parent process - */ -(async () => { - let nextPage; - let foundSHA; - - do { - const { next_page_token, sha } = await findSha(nextPage); - foundSHA = sha; - nextPage = next_page_token; - } while (!foundSHA && nextPage); - - if (foundSHA) { - // send it to parent process - process.stdout.write(foundSHA); - } -})(); - -/** - * Finds the last successful commit and/or token for the next page - * @param {string} pageToken - * @returns { next_page_token?: string, sha?: string } - */ -async function findSha(pageToken) { - return getJson(pageToken ? `${URL}&page-token=${pageToken}` : URL).then( - async ({ next_page_token, items }) => { - const pipeline = await findSuccessfulPipeline(items); - return { - next_page_token, - sha: pipeline ? pipeline.vcs.revision : void 0, - }; - } - ); -} - -/** - * Get successful pipeline run if any - * @param {Object[]} pipelines - * @returns - */ -async function findSuccessfulPipeline(pipelines) { - for (const pipeline of pipelines) { - if ( - !pipeline.errors.length && - commitExists(pipeline.vcs.revision) && - (await isWorkflowSuccessful(pipeline.id)) - ) { - return pipeline; - } - } - return undefined; -} - -/** - * Check if given commit still exists - * @param {string} commitSha - * @returns - */ -function commitExists(commitSha) { - try { - execSync(`git cat-file -e ${commitSha} 2> /dev/null`); - return true; - } catch { - return false; - } -} - -/** - * Check if every workflow in the pipeline is successful - * @param {string} pipelineId - * @returns {boolean} - */ -async function isWorkflowSuccessful(pipelineId) { - return getJson( - `https://circleci.com/api/v2/pipeline/${pipelineId}/workflow` - ).then(({ items }) => items.every((item) => item.status === 'success')); -} - -/** - * Helper function to wrap Https.get as an async call - * @param {string} url - * @returns {Promise} - */ -async function getJson(url) { - return new Promise((resolve, reject) => { - https - .get(url, (res) => { - let data = []; - - res.on('data', (chunk) => { - data.push(chunk); - }); - - res.on('end', () => { - const response = Buffer.concat(data).toString(); - resolve(JSON.parse(response)); - }); - }) - .on('error', (error) => reject(error)); - }); -} diff --git a/scripts/circleci/get-successful-run.sh b/scripts/circleci/get-successful-run.sh deleted file mode 100644 index ba36a37330..0000000000 --- a/scripts/circleci/get-successful-run.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/bash - -PROJECT_SLUG="$1/$2/$3" -BRANCH_NAME=$4 -INPUTS_MAIN_BRANCH_NAME=$5 -INPUTS_ERROR_ON_NO_SUCCESSFUL_WORKFLOW=$6 - -if [ "$BRANCH_NAME" != $INPUTS_MAIN_BRANCH_NAME ]; then - BASE_SHA=$(echo $(git merge-base origin/$INPUTS_MAIN_BRANCH_NAME HEAD)) - echo "" - echo "Branch found. Using base from 'origin/$INPUTS_MAIN_BRANCH_NAME': $BASE_SHA" - echo "" -else - # We will make an https request to CircleCI API getting all the pipelines from the $INPUTS_MAIN_BRANCH_NAME on $PROJECT_SLUG - # For each pipeline we check if it was successful and whether the commit still exists - BASE_SHA=$(node scripts/circleci/find-successful-workflow.js $INPUTS_MAIN_BRANCH_NAME $PROJECT_SLUG ) - - if [ -z $BASE_SHA ]; then - if [ $INPUTS_ERROR_ON_NO_SUCCESSFUL_WORKFLOW = "true" ]; then - echo "" - echo "ERROR: Unable to find a successful workflow run on 'origin/$INPUTS_MAIN_BRANCH_NAME'" - echo "" - echo "NOTE: You have set 'error-on-no-successful-workflow' on the action so this is a hard error." - echo "" - echo "Is it possible that you have no runs currently on 'origin/$INPUTS_MAIN_BRANCH_NAME' in your repo?" - echo "" - echo "- If yes, then you should run the workflow without this flag first." - echo "- If no, then you might have changed your git history and those commits no longer exist." - echo "" - - exit 1 - else - echo "" - echo "WARNING: Unable to find a successful workflow run on 'origin/$INPUTS_MAIN_BRANCH_NAME'" - echo "" - echo "We are therefore defaulting to use HEAD~1 on 'origin/$INPUTS_MAIN_BRANCH_NAME'" - echo "" - echo "NOTE: You can instead make this a hard error by settting 'error-on-no-successful-workflow' on the action in your workflow." - echo "" - - SHA="HEAD~1" - fi - else - echo "" - echo "Found the last successful workflow run on 'origin/$INPUTS_MAIN_BRANCH_NAME'" - echo "" - echo "Commit: $BASE_SHA" - echo "" - fi -fi - -HEAD_SHA=$(git rev-parse HEAD)