Skip to content

Commit

Permalink
feat(ci-context): migrating contexts from functions to classes
Browse files Browse the repository at this point in the history
  • Loading branch information
gperdomor committed Aug 21, 2023
1 parent adc6b64 commit 3bf3ec3
Show file tree
Hide file tree
Showing 30 changed files with 513 additions and 380 deletions.
50 changes: 23 additions & 27 deletions packages/ci-context/src/lib/context.factory.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { logger } from '@nx-tools/core';
import { RunnerContext } from './interfaces';
import * as azure from './utils/azure-devops';
import * as bitbucket from './utils/bitbucket';
import * as circle from './utils/circle';
import * as drone from './utils/drone';
import * as github from './utils/github';
import * as gitlab from './utils/gitlab';
import * as jenkins from './utils/jenkins';
import * as local from './utils/local';
import * as semaphore from './utils/semaphore';
import * as teamcity from './utils/teamcity';
import * as travis from './utils/travis';
import { Azure } from './utils/azure-devops';
import { BitBucket } from './utils/bitbucket';
import { Circle } from './utils/circle';
import { Drone } from './utils/drone';
import { Git } from './utils/git';
import { Github } from './utils/github';
import { Gitlab } from './utils/gitlab';
import { Jenkins } from './utils/jenkins';
import { Semaphore } from './utils/semaphore';
import { Teamcity } from './utils/teamcity';
import { Travis } from './utils/travis';

// eslint-disable-next-line @typescript-eslint/no-var-requires
const ci = require('ci-info');
Expand All @@ -19,59 +19,55 @@ export class ContextProxyFactory {
public static async create(): Promise<RunnerContext> {
if (ci.AZURE_PIPELINES) {
logger.info(`CI Provider: ${ci.name}`);
return azure.context();
return Azure.context();
}

if (ci.BITBUCKET) {
logger.info(`CI Provider: ${ci.name}`);
return bitbucket.context();
return BitBucket.context();
}

if (ci.CIRCLE) {
logger.info(`CI Provider: ${ci.name}`);
return circle.context();
return Circle.context();
}

if (ci.DRONE) {
logger.info(`CI Provider: ${ci.name}`);
return drone.context();
return Drone.context();
}

if (ci.GITHUB_ACTIONS) {
logger.info(`CI Provider: ${ci.name}`);
return github.context();
return Github.context();
}

if (ci.GITLAB) {
logger.info(`CI Provider: ${ci.name}`);
return gitlab.context();
return Gitlab.context();
}

if (ci.JENKINS) {
logger.info(`CI Provider: ${ci.name}`);
return jenkins.context();
return Jenkins.context();
}

if (ci.SEMAPHORE) {
logger.info(`CI Provider: ${ci.name}`);
return semaphore.context();
return Semaphore.context();
}

if (ci.TRAVIS) {
logger.info(`CI Provider: ${ci.name}`);
return travis.context();
return Travis.context();
}

if (ci.TEAMCITY) {
logger.info(`CI Provider: ${ci.name}`);
return teamcity.context();
return Teamcity.context();
}

if (!ci.isCI || process.env['CI_CONTEXT_FALLBACK_TO_LOCAL']?.toLowerCase() === 'true') {
logger.info(`Unsupported CI Provider... Using Local Environment as fallback`);
return local.context();
}

throw new Error('Unsupported CI Provider');
logger.info(`Unsupported CI Provider... Using Git as fallback`);
return Git.context();
}
}
2 changes: 2 additions & 0 deletions packages/ci-context/src/lib/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ export type RepoMetadata = Pick<
>;

export interface RunnerContext {
name: string;
actor: string;
eventName: string;
job: string;
payload: Record<string, any>;
ref: string;
runId: number;
runNumber: number;
repoUrl: string;
sha: string;
}
8 changes: 2 additions & 6 deletions packages/ci-context/src/lib/repo.factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import * as azure from './utils/azure-devops';
import * as bitbucket from './utils/bitbucket';
import * as circle from './utils/circle';
import * as drone from './utils/drone';
import * as git from './utils/git';
import * as github from './utils/github';
import * as gitlab from './utils/gitlab';
import * as jenkins from './utils/jenkins';
import * as local from './utils/local';
import * as semaphore from './utils/semaphore';
import * as teamcity from './utils/teamcity';
import * as travis from './utils/travis';
Expand Down Expand Up @@ -56,10 +56,6 @@ export class RepoProxyFactory {
return teamcity.repo();
}

if (!ci.isCI || process.env['CI_CONTEXT_FALLBACK_TO_LOCAL']?.toLowerCase() === 'true') {
return local.repo();
}

throw new Error('Unsupported CI Provider');
return git.repo();
}
}
18 changes: 12 additions & 6 deletions packages/ci-context/src/lib/utils/azure-devops.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import mockedEnv, { RestoreFn } from 'mocked-env';
import { RunnerContext } from '../interfaces';
import * as devops from './azure-devops';
import { Azure } from './azure-devops';

describe('Azure DevOps Context', () => {
let restore: RestoreFn;
Expand All @@ -13,13 +14,14 @@ describe('Azure DevOps Context', () => {
BUILD_SOURCEVERSIONAUTHOR: 'devops-actor',
AGENT_JOBNAME: 'devops-job',
BUILD_BUILDID: '40',
BUILD_REPOSITORY_URI: 'https://gitlab.com/gperdomor/nx-tools',
BUILD_REPOSITORY_URI: 'https://azure.com/gperdomor/nx-tools',
},
{ clear: true }
);
});

afterEach(() => {
jest.restoreAllMocks();
restore();
});

Expand All @@ -31,16 +33,18 @@ describe('Azure DevOps Context', () => {
});

it('Should be take proper context values', async () => {
context = await devops.context();
context = await Azure.context();

expect(context).toMatchObject({
expect(context).toEqual({
name: 'AZURE',
actor: 'devops-actor',
eventName: 'pull_request',
job: 'devops-job',
payload: {},
ref: 'refs/heads/devops-ref-slug',
runId: 40,
runNumber: 40,
repoUrl: 'https://azure.com/gperdomor/nx-tools',
sha: 'devops-sha',
});
});
Expand All @@ -52,16 +56,18 @@ describe('Azure DevOps Context', () => {
});

it('Should be take proper context values', async () => {
context = await devops.context();
context = await Azure.context();

expect(context).toMatchObject({
expect(context).toEqual({
name: 'AZURE',
actor: 'devops-actor',
eventName: 'unknown',
job: 'devops-job',
payload: {},
ref: 'refs/heads/devops-ref-slug',
runId: 40,
runNumber: 40,
repoUrl: 'https://azure.com/gperdomor/nx-tools',
sha: 'devops-sha',
});
});
Expand All @@ -75,7 +81,7 @@ describe('Azure DevOps Context', () => {
expect(repo).toMatchObject({
default_branch: '',
description: '',
html_url: 'https://gitlab.com/gperdomor/nx-tools',
html_url: 'https://azure.com/gperdomor/nx-tools',
license: null,
name: 'devops-job',
});
Expand Down
26 changes: 15 additions & 11 deletions packages/ci-context/src/lib/utils/azure-devops.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { RepoMetadata, RunnerContext } from '../interfaces';

export async function context(): Promise<RunnerContext> {
return {
actor: process.env['BUILD_SOURCEVERSIONAUTHOR']!,
eventName: process.env['SYSTEM_PULLREQUEST_PULLREQUESTID'] ? 'pull_request' : 'unknown',
job: process.env['AGENT_JOBNAME']!,
payload: {},
ref: process.env['SYSTEM_PULLREQUEST_SOURCEBRANCH'] || (process.env['BUILD_SOURCEBRANCH'] as string),
runId: parseInt(process.env['BUILD_BUILDID']!, 10),
runNumber: parseInt(process.env['BUILD_BUILDID']!, 10),
sha: process.env['BUILD_SOURCEVERSION']!,
};
export class Azure {
public static async context(): Promise<RunnerContext> {
return {
name: 'AZURE',
actor: process.env['BUILD_SOURCEVERSIONAUTHOR']!,
eventName: process.env['SYSTEM_PULLREQUEST_PULLREQUESTID'] ? 'pull_request' : 'unknown',
job: process.env['AGENT_JOBNAME']!,
payload: {},
ref: process.env['SYSTEM_PULLREQUEST_SOURCEBRANCH'] || (process.env['BUILD_SOURCEBRANCH'] as string),
runId: parseInt(process.env['BUILD_BUILDID']!, 10),
runNumber: parseInt(process.env['BUILD_BUILDID']!, 10),
repoUrl: process.env['BUILD_REPOSITORY_URI']!,
sha: process.env['BUILD_SOURCEVERSION']!,
};
}
}

export async function repo(): Promise<RepoMetadata> {
Expand Down
21 changes: 15 additions & 6 deletions packages/ci-context/src/lib/utils/bitbucket.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import mockedEnv, { RestoreFn } from 'mocked-env';
import { RunnerContext } from '../interfaces';
import * as bitbucket from './bitbucket';
import { BitBucket } from './bitbucket';

describe('CircleCI Context', () => {
let restore: RestoreFn;
Expand All @@ -17,43 +18,49 @@ describe('CircleCI Context', () => {
BITBUCKET_BUILD_NUMBER: '50',
BITBUCKET_REPO_FULL_NAME: 'gperdomor/nx-tools',
BITBUCKET_WORKSPACE: 'nx-tools',
BITBUCKET_GIT_HTTP_ORIGIN: 'https://bitbucket.org/gperdomor/nx-tools',
},
{ clear: true }
);
});

afterEach(() => {
jest.restoreAllMocks();
restore();
});

describe('context', () => {
it('Should be take proper values', async () => {
context = await bitbucket.context();
context = await BitBucket.context();

expect(context).toMatchObject({
expect(context).toEqual({
name: 'BITBUCKET',
actor: 'bitbucket-actor-uuid',
eventName: 'pull_request',
job: 'bitbucket-job-uuid',
payload: {},
ref: 'refs/heads/bitbucket-ref-slug',
runId: 50,
runNumber: 50,
repoUrl: 'https://bitbucket.org/gperdomor/nx-tools',
sha: 'bitbucket-sha',
});
});

it('Should be take proper values - no pr', async () => {
delete process.env['BITBUCKET_PR_ID'];
context = await bitbucket.context();
context = await BitBucket.context();

expect(context).toMatchObject({
expect(context).toEqual({
name: 'BITBUCKET',
actor: 'bitbucket-actor-uuid',
eventName: 'unknown',
job: 'bitbucket-job-uuid',
payload: {},
ref: 'refs/heads/bitbucket-ref-slug',
runId: 50,
runNumber: 50,
repoUrl: 'https://bitbucket.org/gperdomor/nx-tools',
sha: 'bitbucket-sha',
});
});
Expand All @@ -72,16 +79,18 @@ describe('CircleCI Context', () => {
});

it('Should be take proper context values', async () => {
context = await bitbucket.context();
context = await BitBucket.context();

expect(context).toMatchObject({
expect(context).toEqual({
name: 'BITBUCKET',
actor: 'bitbucket-actor-uuid',
eventName: 'pull_request',
job: 'bitbucket-job-uuid',
payload: {},
ref: 'refs/tags/bitbucket-tag',
runId: 50,
runNumber: 50,
repoUrl: 'https://bitbucket.org/gperdomor/nx-tools',
sha: 'bitbucket-sha',
});
});
Expand Down
30 changes: 17 additions & 13 deletions packages/ci-context/src/lib/utils/bitbucket.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { RepoMetadata, RunnerContext } from '../interfaces';

export async function context(): Promise<RunnerContext> {
return {
actor: process.env['BITBUCKET_STEP_TRIGGERER_UUID']!,
eventName: process.env['BITBUCKET_PR_ID'] ? 'pull_request' : 'unknown',
job: process.env['BITBUCKET_STEP_UUID']!,
payload: {},
ref: process.env['BITBUCKET_TAG']
? `refs/tags/${process.env['BITBUCKET_TAG']}`
: `refs/heads/${process.env['BITBUCKET_BRANCH']}`,
runId: parseInt(process.env['BITBUCKET_BUILD_NUMBER']!, 10),
runNumber: parseInt(process.env['BITBUCKET_BUILD_NUMBER']!, 10),
sha: process.env['BITBUCKET_COMMIT']!,
};
export class BitBucket {
public static async context(): Promise<RunnerContext> {
return {
name: 'BITBUCKET',
actor: process.env['BITBUCKET_STEP_TRIGGERER_UUID']!,
eventName: process.env['BITBUCKET_PR_ID'] ? 'pull_request' : 'unknown',
job: process.env['BITBUCKET_STEP_UUID']!,
payload: {},
ref: process.env['BITBUCKET_TAG']
? `refs/tags/${process.env['BITBUCKET_TAG']}`
: `refs/heads/${process.env['BITBUCKET_BRANCH']}`,
runId: parseInt(process.env['BITBUCKET_BUILD_NUMBER']!, 10),
runNumber: parseInt(process.env['BITBUCKET_BUILD_NUMBER']!, 10),
repoUrl: process.env['BITBUCKET_GIT_HTTP_ORIGIN']!,
sha: process.env['BITBUCKET_COMMIT']!,
};
}
}

export async function repo(): Promise<RepoMetadata> {
Expand Down
Loading

0 comments on commit 3bf3ec3

Please sign in to comment.