fix(html-report): only invoke git once (#13165)
This commit is contained in:
parent
eb09306db2
commit
5e17ed137b
|
|
@ -104,9 +104,6 @@ const MetadataView: React.FC<Metadata> = metadata => {
|
||||||
icon='externalLink'
|
icon='externalLink'
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
{metadata['revision.localPendingChanges'] &&
|
|
||||||
<p style={{ fontStyle: 'italic', color: 'var(--color-fg-subtle)' }}>This report was generated with <strong>uncommitted changes</strong>.</p>
|
|
||||||
}
|
|
||||||
{metadata['generatedAt'] &&
|
{metadata['generatedAt'] &&
|
||||||
<p style={{ fontStyle: 'italic', color: 'var(--color-fg-subtle)' }}>Report generated on {Intl.DateTimeFormat(undefined, { dateStyle: 'full', timeStyle: 'long' }).format(metadata['generatedAt'])}</p>
|
<p style={{ fontStyle: 'italic', color: 'var(--color-fg-subtle)' }}>Report generated on {Intl.DateTimeFormat(undefined, { dateStyle: 'full', timeStyle: 'long' }).format(metadata['generatedAt'])}</p>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { spawnAsync } from 'playwright-core/lib/utils/utils';
|
import { createGuid, spawnAsync } from 'playwright-core/lib/utils/utils';
|
||||||
|
|
||||||
const GIT_OPERATIONS_TIMEOUT_MS = 1500;
|
const GIT_OPERATIONS_TIMEOUT_MS = 1500;
|
||||||
const kContentTypePlainText = 'text/plain';
|
const kContentTypePlainText = 'text/plain';
|
||||||
|
|
@ -26,24 +26,16 @@ export interface Attachment {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const gitStatusFromCLI = async (gitDir: string): Promise<Attachment[]> => {
|
export const gitStatusFromCLI = async (gitDir: string): Promise<Attachment[]> => {
|
||||||
const execGit = async (args: string[]) => {
|
const separator = `:${createGuid().slice(0, 4)}:`;
|
||||||
const { code, stdout } = await spawnAsync('git', args, { stdio: 'pipe', cwd: gitDir, timeout: GIT_OPERATIONS_TIMEOUT_MS });
|
const { code, stdout } = await spawnAsync(
|
||||||
if (!!code)
|
'git',
|
||||||
throw new Error('Exited with non-zero code.');
|
['show', '-s', `--format=%H${separator}%s${separator}%an${separator}%ae${separator}%ct`, 'HEAD'],
|
||||||
|
{ stdio: 'pipe', cwd: gitDir, timeout: GIT_OPERATIONS_TIMEOUT_MS }
|
||||||
return stdout.trim();
|
);
|
||||||
};
|
if (code)
|
||||||
|
return [];
|
||||||
await execGit(['--help']).catch(() => { throw new Error('git --help failed; is git installed?');});
|
const showOutput = stdout.trim();
|
||||||
const [ status, sha, subject, authorName, authorEmail, rawTimestamp ] = await Promise.all([
|
const [sha, subject, authorName, authorEmail, rawTimestamp] = showOutput.split(separator);
|
||||||
execGit(['status', '--porcelain=v1']),
|
|
||||||
execGit(['rev-parse', 'HEAD']),
|
|
||||||
execGit(['show', '-s', '--format=%s', 'HEAD']),
|
|
||||||
execGit(['show', '-s', '--format=%an', 'HEAD']),
|
|
||||||
execGit(['show', '-s', '--format=%ae', 'HEAD']),
|
|
||||||
execGit(['show', '-s', '--format=%ct', 'HEAD']),
|
|
||||||
]).catch(() => { throw new Error('one or more git commands failed');});
|
|
||||||
|
|
||||||
let timestamp: number = Number.parseInt(rawTimestamp, 10);
|
let timestamp: number = Number.parseInt(rawTimestamp, 10);
|
||||||
timestamp = Number.isInteger(timestamp) ? timestamp * 1000 : 0;
|
timestamp = Number.isInteger(timestamp) ? timestamp * 1000 : 0;
|
||||||
|
|
||||||
|
|
@ -53,7 +45,6 @@ export const gitStatusFromCLI = async (gitDir: string): Promise<Attachment[]> =>
|
||||||
{ name: 'revision.email', body: Buffer.from(authorEmail), contentType: kContentTypePlainText },
|
{ name: 'revision.email', body: Buffer.from(authorEmail), contentType: kContentTypePlainText },
|
||||||
{ name: 'revision.subject', body: Buffer.from(subject), contentType: kContentTypePlainText },
|
{ name: 'revision.subject', body: Buffer.from(subject), contentType: kContentTypePlainText },
|
||||||
{ name: 'revision.timestamp', body: Buffer.from(JSON.stringify(timestamp)), contentType: kContentTypeJSON },
|
{ name: 'revision.timestamp', body: Buffer.from(JSON.stringify(timestamp)), contentType: kContentTypeJSON },
|
||||||
{ name: 'revision.localPendingChanges', body: Buffer.from(!!status + ''), contentType: kContentTypePlainText },
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import * as ci from '@playwright/test/lib/ci';
|
||||||
async function globalSetup(config: FullConfig) {
|
async function globalSetup(config: FullConfig) {
|
||||||
config.attachments = [
|
config.attachments = [
|
||||||
...await ci.generationTimestamp(),
|
...await ci.generationTimestamp(),
|
||||||
...await ci.gitStatusFromCLI(config.rootDir).catch(() => []),
|
...await ci.gitStatusFromCLI(config.rootDir),
|
||||||
...await ci.githubEnv(),
|
...await ci.githubEnv(),
|
||||||
// In the future, we would add some additional plugins like:
|
// In the future, we would add some additional plugins like:
|
||||||
// ...await ci.azurePipelinePlugin(),
|
// ...await ci.azurePipelinePlugin(),
|
||||||
|
|
|
||||||
|
|
@ -679,7 +679,7 @@ test('should include metadata', async ({ runInlineTest, showReport, page }) => {
|
||||||
async function globalSetup(config: FullConfig) {
|
async function globalSetup(config: FullConfig) {
|
||||||
config.attachments = [
|
config.attachments = [
|
||||||
...await ci.generationTimestamp(),
|
...await ci.generationTimestamp(),
|
||||||
...await ci.gitStatusFromCLI(config.rootDir).catch(() => []),
|
...await ci.gitStatusFromCLI(config.rootDir),
|
||||||
...await ci.githubEnv(),
|
...await ci.githubEnv(),
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
@ -711,6 +711,5 @@ test('should include metadata', async ({ runInlineTest, showReport, page }) => {
|
||||||
await expect.soft(metadata).toContainText('William');
|
await expect.soft(metadata).toContainText('William');
|
||||||
await expect.soft(metadata).toContainText('shakespeare@example.local');
|
await expect.soft(metadata).toContainText('shakespeare@example.local');
|
||||||
await expect.soft(metadata.locator('text=CI/CD Logs')).toHaveAttribute('href', 'https://playwright.dev/microsoft/playwright-example-for-test/actions/runs/example-run-id');
|
await expect.soft(metadata.locator('text=CI/CD Logs')).toHaveAttribute('href', 'https://playwright.dev/microsoft/playwright-example-for-test/actions/runs/example-run-id');
|
||||||
await expect.soft(metadata).toContainText('uncommitted changes');
|
|
||||||
await expect.soft(metadata.locator('text=Report generated on')).toContainText(/AM|PM/);
|
await expect.soft(metadata.locator('text=Report generated on')).toContainText(/AM|PM/);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue