Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into tom/ap-3462-mark-addo…
Browse files Browse the repository at this point in the history
…n-initiated-builds-as-local
  • Loading branch information
tmeasday committed Aug 21, 2023
2 parents bb8c2b9 + 29d4177 commit f94fc3b
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 7 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 6.22.0 - 2023-08-15

- [798](https://github.com/chromaui/chromatic-cli/pull/798) Calculate and record `uncommittedHash` when creating a build

# 6.21.0 - 2023-08-07

- [794](https://github.com/chromaui/chromatic-cli/pull/794) Add `getGitInfo` function exported by the Node API
Expand Down
23 changes: 23 additions & 0 deletions node-src/git/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,29 @@ export async function getBranch() {
}
}

// Retrieve the hash of all uncommitted files, which includes staged, unstaged, and untracked files,
// excluding deleted files (which can't be hashed) and ignored files. There is no one single Git
// command to reliably get this information, so we use a combination of commands grouped together.
export async function getUncommittedHash() {
const listStagedFiles = 'git diff --name-only --diff-filter=d --cached';
const listUnstagedFiles = 'git diff --name-only --diff-filter=d';
const listUntrackedFiles = 'git ls-files --others --exclude-standard';
const listUncommittedFiles = [listStagedFiles, listUnstagedFiles, listUntrackedFiles].join(';');

const uncommittedHash = (
await execGitCommand(
// Pass the combined list of filenames to hash-object to retrieve a list of hashes. Then pass
// the list of hashes to hash-object again to retrieve a single hash of all hashes. We use
// stdin to avoid the limit on command line arguments.
`(${listUncommittedFiles}) | git hash-object --stdin-paths | git hash-object --stdin`
)
).trim();

// In case there are no uncommited changes (empty list), we always get this same hash.
const noChangesHash = 'e69de29bb2d1d6434b8b29ae775ad8c2e48c5391';
return uncommittedHash === noChangesHash ? '' : uncommittedHash;
}

export async function hasPreviousCommit() {
const result = await execGitCommand(`git --no-pager log -n 1 --skip=1 --format="%H"`);
return !!result.trim();
Expand Down
10 changes: 6 additions & 4 deletions node-src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import checkPackageJson from './lib/checkPackageJson';
import { writeChromaticDiagnostics } from './lib/writeChromaticDiagnostics';
import invalidPackageJson from './ui/messages/errors/invalidPackageJson';
import noPackageJson from './ui/messages/errors/noPackageJson';
import { getBranch, getCommit, getSlug } from './git/git';
import { getBranch, getCommit, getSlug, getUncommittedHash } from './git/git';

/**
Make keys of `T` outside of `R` optional.
Expand Down Expand Up @@ -112,11 +112,12 @@ export async function runAll(ctx, options?: Options) {
}
}

export type GitInfo = {
export interface GitInfo {
branch: string;
commit: string;
slug: string;
};
uncommittedHash: string;
}

export async function getGitInfo(): Promise<GitInfo> {
const branch = await getBranch();
Expand All @@ -126,5 +127,6 @@ export async function getGitInfo(): Promise<GitInfo> {
const [ownerName, repoName, ...rest] = slug ? slug.split('/') : [];
const isValidSlug = !!ownerName && !!repoName && !rest.length;

return { branch, commit, slug: isValidSlug ? slug : '' };
const uncommittedHash = await getUncommittedHash();
return { branch, commit, slug: isValidSlug ? slug : '', uncommittedHash };
}
1 change: 1 addition & 0 deletions node-src/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ jest.mock('./git/git', () => ({
getVersion: () => Promise.resolve('2.24.1'),
getChangedFiles: () => Promise.resolve(['src/foo.stories.js']),
getRepositoryRoot: () => Promise.resolve(process.cwd()),
getUncommittedHash: () => Promise.resolve('abc123'),
}));

jest.mock('./git/getParentCommits', () => ({
Expand Down
4 changes: 4 additions & 0 deletions node-src/tasks/gitInfo.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ const getChangedFilesWithReplacement = <
>getChangedFilesWithReplacementUnmocked;
const getSlug = <jest.MockedFunction<typeof git.getSlug>>git.getSlug;
const getVersion = <jest.MockedFunction<typeof git.getVersion>>git.getVersion;
const getUncommittedHash = <jest.MockedFunction<typeof git.getUncommittedHash>>(
git.getUncommittedHash
);

const getBaselineBuilds = <jest.MockedFunction<typeof getBaselineBuildsUnmocked>>(
getBaselineBuildsUnmocked
Expand All @@ -42,6 +45,7 @@ const client = { runQuery: jest.fn(), setAuthorization: jest.fn() };

beforeEach(() => {
getCommitAndBranch.mockResolvedValue(commitInfo);
getUncommittedHash.mockResolvedValue('abc123');
getParentCommits.mockResolvedValue(['asd2344']);
getBaselineBuilds.mockResolvedValue([]);
getChangedFilesWithReplacement.mockResolvedValue({ changedFiles: [] });
Expand Down
8 changes: 6 additions & 2 deletions node-src/tasks/gitInfo.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import picomatch from 'picomatch';

import getCommitAndBranch from '../git/getCommitAndBranch';
import { getSlug, getVersion } from '../git/git';
import { getSlug, getUncommittedHash, getVersion } from '../git/git';
import { getParentCommits } from '../git/getParentCommits';
import { getBaselineBuilds } from '../git/getBaselineBuilds';
import { exitCodes, setExitCode } from '../lib/setExitCode';
Expand Down Expand Up @@ -62,8 +62,12 @@ export const setGitInfo = async (ctx: Context, task: Task) => {
} = ctx.options;

ctx.git = {
version: await getVersion(),
...(await getCommitAndBranch(ctx, { branchName, patchBaseRef, ci })),
uncommittedHash: await getUncommittedHash().catch((e) => {
ctx.log.warn('Failed to retrieve uncommitted files hash', e);
return null;
}),
version: await getVersion(),
};

if (!ctx.git.slug) {
Expand Down
1 change: 1 addition & 0 deletions node-src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ export interface Context {
committedAt: number;
slug?: string;
mergeCommit?: string;
uncommittedHash?: string;
parentCommits?: string[];
baselineCommits?: string[];
changedFiles?: string[];
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "chromatic",
"version": "6.22.0-canary.0",
"version": "6.22.0",
"description": "Automate visual testing across browsers. Gather UI feedback. Versioned documentation.",
"keywords": [
"storybook-addon",
Expand Down

0 comments on commit f94fc3b

Please sign in to comment.