Skip to content

Commit

Permalink
Merge pull request #304 from chromaui/determine-affected-stories
Browse files Browse the repository at this point in the history
Support only testing components affected by recent git changes
  • Loading branch information
ghengeveld committed Apr 29, 2021
2 parents 386c167 + 6ed15f2 commit 302f19f
Show file tree
Hide file tree
Showing 52 changed files with 1,088 additions and 743 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/action-run.yml
@@ -1,9 +1,9 @@
name: "self test development-like"
name: "Action"
on:
push:

jobs:
test:
self-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
Expand All @@ -12,6 +12,6 @@ jobs:
- run: yarn build-storybook
- uses: ./
with:
projectToken: 5oy3iw6rkio
token: ${{ secrets.GITHUB_TOKEN }}
projectToken: 5oy3iw6rkio
storybookBuildDir: storybook-static
6 changes: 4 additions & 2 deletions .github/workflows/chromatic-action.yml
@@ -1,4 +1,4 @@
name: "Chromatic via action"
name: "Chromatic (action)"
on: [push, pull_request, pull_request_review, pull_request_target]

jobs:
Expand All @@ -10,4 +10,6 @@ jobs:
- uses: chromaui/action@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
projectToken: gcaw1ai2dgo
projectToken: gcaw1ai2dgo
exitZeroOnChanges: true
exitOnceUploaded: true
3 changes: 1 addition & 2 deletions .github/workflows/chromatic-manual.yml
@@ -1,4 +1,4 @@
name: "Chromatic via manual"
name: "Chromatic (manual)"
on: [push]
# do not use pull_request here, it report the wrong commit_sha and commit_ref

Expand All @@ -18,4 +18,3 @@ jobs:
run: yarn chromatic
env:
CHROMATIC_PROJECT_TOKEN: gcaw1ai2dgo
CHROMATIC_APP_CODE: gcaw1ai2dgo
10 changes: 5 additions & 5 deletions .github/workflows/chromatic-staging-action.yml
@@ -1,4 +1,4 @@
name: "[Staging] Chromatic via action"
name: "[Staging] Chromatic (action)"
on: [push, pull_request, pull_request_target, pull_request_review]

jobs:
Expand All @@ -10,10 +10,10 @@ jobs:
- uses: chromaui/action@v1
env:
DEBUG: chromatic-cli
CHROMATIC_APP_CODE: mpm7osoy9sa
CHROMATIC_PROJECT_TOKEN: mpm7osoy9sa
CHROMATIC_INDEX_URL: https://www.staging-chromatic.com
with:
appCode: mpm7osoy9sa
token: ${{ secrets.GITHUB_TOKEN }}
projectToken: mpm7osoy9sa
token: ${{ secrets.GITHUB_TOKEN }}
onlyChanged: true
exitZeroOnChanges: true
exitOnceUploaded: true
7 changes: 3 additions & 4 deletions .github/workflows/chromatic-staging-manual.yml
@@ -1,4 +1,4 @@
name: "[Staging] Chromatic via manual"
name: "[Staging] Chromatic (manual)"
on: [push]
# do not use pull_request here, it report the wrong commit_sha and commit_ref

Expand All @@ -15,8 +15,7 @@ jobs:
- name: prep package
run: ./scripts/rename.js storybook-chromatic
- name: run chromatic
run: yarn chromatic
run: yarn chromatic --only-changed
env:
CHROMATIC_APP_CODE: mpm7osoy9sa
CHROMATIC_PROJECT_TOKEN: mpm7osoy9sa
CHROMATIC_INDEX_URL: https://www.staging-chromatic.com
CHROMATIC_INDEX_URL: https://www.staging-chromatic.com
7 changes: 3 additions & 4 deletions .github/workflows/chromatic-staging-windows.yml
@@ -1,4 +1,4 @@
name: "[Staging] Chromatic via windows"
name: "[Staging] Chromatic (windows)"
on: [push]
# do not use pull_request here, it report the wrong commit_sha and commit_ref

Expand All @@ -15,8 +15,7 @@ jobs:
- name: prep package
run: node ./scripts/rename.js storybook-chromatic
- name: run chromatic
run: yarn chromatic
run: yarn chromatic --only-changed
env:
CHROMATIC_APP_CODE: mpm7osoy9sa
CHROMATIC_PROJECT_TOKEN: mpm7osoy9sa
CHROMATIC_INDEX_URL: https://www.staging-chromatic.com
CHROMATIC_INDEX_URL: https://www.staging-chromatic.com
3 changes: 1 addition & 2 deletions .github/workflows/chromatic-windows.yml
@@ -1,4 +1,4 @@
name: "Chromatic via windows"
name: "Chromatic (windows)"
on: [push]
# do not use pull_request here, it report the wrong commit_sha and commit_ref

Expand All @@ -18,4 +18,3 @@ jobs:
run: yarn chromatic
env:
CHROMATIC_PROJECT_TOKEN: gcaw1ai2dgo
CHROMATIC_APP_CODE: gcaw1ai2dgo
6 changes: 6 additions & 0 deletions action.yml
Expand Up @@ -30,6 +30,12 @@ inputs:
skip:
description: 'Skip Chromatic tests, but mark the commit as passing'
required: false
only:
description: 'Only run a single story or a subset of stories'
required: false
onlyChanged:
description: 'Only run stories affected by files changed since the baseline build'
required: false
doNotStart:
description: 'Do not attempt to start or build; use if your Storybook is already running'
required: false
Expand Down
6 changes: 5 additions & 1 deletion action/main.js
Expand Up @@ -136,7 +136,7 @@ function runChromatic(options) {
}
function run() {
return __awaiter(this, void 0, void 0, function () {
var commit, branch, sha, projectToken, workingDir, buildScriptName, scriptName, exec, skip, doNotStart, storybookPort, storybookUrl, storybookBuildDir, storybookHttps, storybookCert, storybookKey, storybookCa, preserveMissing, autoAcceptChanges, allowConsoleErrors, exitZeroOnChanges, exitOnceUploaded, ignoreLastBuildOnBranch, output, e_1;
var commit, branch, sha, projectToken, workingDir, buildScriptName, scriptName, exec, skip, only, onlyChanged, doNotStart, storybookPort, storybookUrl, storybookBuildDir, storybookHttps, storybookCert, storybookKey, storybookCa, preserveMissing, autoAcceptChanges, allowConsoleErrors, exitZeroOnChanges, exitOnceUploaded, ignoreLastBuildOnBranch, output, e_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
Expand All @@ -154,6 +154,8 @@ function run() {
scriptName = core_1.getInput('scriptName');
exec = core_1.getInput('exec');
skip = core_1.getInput('skip');
only = core_1.getInput('only');
onlyChanged = core_1.getInput('onlyChanged');
doNotStart = core_1.getInput('doNotStart');
storybookPort = core_1.getInput('storybookPort');
storybookUrl = core_1.getInput('storybookUrl');
Expand All @@ -178,6 +180,8 @@ function run() {
scriptName: maybe(scriptName),
exec: maybe(exec),
skip: maybe(skip),
only: maybe(only),
onlyChanged: maybe(onlyChanged),
doNotStart: maybe(doNotStart),
storybookPort: maybe(storybookPort),
storybookUrl: maybe(storybookUrl),
Expand Down
4 changes: 4 additions & 0 deletions action/main.ts
Expand Up @@ -102,6 +102,8 @@ async function run() {
const scriptName = getInput('scriptName');
const exec = getInput('exec');
const skip = getInput('skip');
const only = getInput('only');
const onlyChanged = getInput('onlyChanged');
const doNotStart = getInput('doNotStart');
const storybookPort = getInput('storybookPort');
const storybookUrl = getInput('storybookUrl');
Expand All @@ -128,6 +130,8 @@ async function run() {
scriptName: maybe(scriptName),
exec: maybe(exec),
skip: maybe(skip),
only: maybe(only),
onlyChanged: maybe(onlyChanged),
doNotStart: maybe(doNotStart),
storybookPort: maybe(storybookPort),
storybookUrl: maybe(storybookUrl),
Expand Down
63 changes: 41 additions & 22 deletions bin/git/git.js
Expand Up @@ -63,6 +63,21 @@ const TesterHasBuildsWithCommitsQuery = gql`
}
`;

const TesterBaselineCommitsQuery = gql`
query TesterBaselineCommitsQuery($branch: String!, $parentCommits: [String!]!) {
app {
baselineBuilds(branch: $branch, parentCommits: $parentCommits) {
number
status
commit
committedAt
changeCount
webUrl
}
}
}
`;

export async function getVersion() {
const result = await execGitCommand(`git --version`);
return result.replace('git version ', '');
Expand Down Expand Up @@ -229,19 +244,15 @@ async function step(
});
}

export async function getBaselineCommits(
{ client, log },
{ branch, ignoreLastBuildOnBranch = false } = {}
export async function getParentCommits(
{ client, git, log },
{ ignoreLastBuildOnBranch = false } = {}
) {
const { commit, committedAt } = await getCommit();
const { branch, commit, committedAt } = git;

// Include the latest build from this branch as an ancestor of the current build
const {
app: { firstBuild, lastBuild, pullRequest },
} = await client.runQuery(TesterFirstCommittedAtQuery, {
branch,
commit,
});
const { app } = await client.runQuery(TesterFirstCommittedAtQuery, { branch, commit });
const { firstBuild, lastBuild, pullRequest } = app;
log.debug(
`App firstBuild: %o, lastBuild: %o, pullRequest: %o`,
firstBuild,
Expand All @@ -255,9 +266,9 @@ export async function getBaselineCommits(
}

const initialCommitsWithBuilds = [];
const extraBaselineCommits = [];
const extraParentCommits = [];

// Add the most recent build on the branch as a (potential) baseline build, unless:
// Add the most recent build on the branch as a parent build, unless:
// - the user opts out with `--ignore-last-build-on-branch`
// - the commit is newer than the build we are running, in which case we doing this build out
// of order and that could lead to problems.
Expand All @@ -275,14 +286,14 @@ export async function getBaselineCommits(
initialCommitsWithBuilds.push(lastBuild.commit);
} else {
log.debug(
`Last branch build commit ${lastBuild.commit} not in index, blindly appending to baselines`
`Last branch build commit ${lastBuild.commit} not in index, blindly appending to parents`
);
extraBaselineCommits.push(lastBuild.commit);
extraParentCommits.push(lastBuild.commit);
}
}

// Add the most recent build on a (merged) branch as a (potential) baseline if we think
// this commit was the commit that merged the PR.
// Add the most recent build on a (merged) branch as a parent if we think this was the commit that
// merged the pull request.
// @see https://www.chromatic.com/docs/branching-and-baselines#squash-and-rebase-merging
if (pullRequest && pullRequest.lastHeadBuild) {
if (await commitExists(pullRequest.lastHeadBuild.commit)) {
Expand All @@ -292,9 +303,9 @@ export async function getBaselineCommits(
initialCommitsWithBuilds.push(pullRequest.lastHeadBuild.commit);
} else {
log.debug(
`Merged PR build commit ${pullRequest.lastHeadBuild.commit} not in index, blindly appending to baselines`
`Merged PR build commit ${pullRequest.lastHeadBuild.commit} not in index, blindly appending to parents`
);
extraBaselineCommits.push(pullRequest.lastHeadBuild.commit);
extraParentCommits.push(pullRequest.lastHeadBuild.commit);
}
}

Expand All @@ -312,10 +323,18 @@ export async function getBaselineCommits(
log.debug(`Final commitsWithBuilds: ${commitsWithBuilds}`);

// For any pair A,B of builds, there is no point in using B if it is an ancestor of A.
return [
...extraBaselineCommits,
...(await maximallyDescendentCommits({ log }, commitsWithBuilds)),
];
return [...extraParentCommits, ...(await maximallyDescendentCommits({ log }, commitsWithBuilds))];
}

export async function getBaselineBuilds({ client }, { branch, parentCommits }) {
const { app } = await client.runQuery(TesterBaselineCommitsQuery, { branch, parentCommits });
return app.baselineBuilds;
}

export async function getChangedFiles(baseCommit, headCommit = '') {
// Note that an empty headCommit will include uncommitted (staged or unstaged) changes.
const files = await execGitCommand(`git diff --name-only ${baseCommit} ${headCommit}`);
return files.split(EOL).filter(Boolean);
}

/**
Expand Down

0 comments on commit 302f19f

Please sign in to comment.