Skip to content

Commit

Permalink
feat(core): add CI file generator logic WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
meeroslav committed Apr 4, 2022
1 parent ba3d962 commit deb348e
Show file tree
Hide file tree
Showing 8 changed files with 400 additions and 4 deletions.
4 changes: 4 additions & 0 deletions packages/nx/src/utils/package-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export type PackageManager = 'yarn' | 'pnpm' | 'npm';

export interface PackageManagerCommands {
install: string;
ciInstall: string;
add: string;
addDev: string;
addGlobal: string;
Expand Down Expand Up @@ -45,6 +46,7 @@ export function getPackageManagerCommand(
const commands: { [pm in PackageManager]: () => PackageManagerCommands } = {
yarn: () => ({
install: 'yarn',
ciInstall: 'yarn --frozen-lockfile',
add: 'yarn add -W',
addDev: 'yarn add -D -W',
addGlobal: 'yarn global add',
Expand All @@ -61,6 +63,7 @@ export function getPackageManagerCommand(
}
return {
install: 'pnpm install --no-frozen-lockfile', // explicitly disable in case of CI
ciInstall: 'pnpm install --frozen-lockfile',
add: 'pnpm add',
addDev: 'pnpm add -D',
addGlobal: 'pnpm add -g',
Expand All @@ -75,6 +78,7 @@ export function getPackageManagerCommand(

return {
install: 'npm install',
ciInstall: 'npm ci',
add: 'npm install',
addDev: 'npm install -D',
addGlobal: 'npm install -g',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`lib should generate azure CI config 1`] = `
"name: build
trigger:
- main
pr:
- main
variables:
- name: NX_CLOUD_DISTRIBUTED_EXECUTION
value: 'true'
- name: NX_DISTRIBUTED_TASK_EXECUTION_AGENT_COUNT
value: 4
- name: NX_VERBOSE_LOGGING
value: 'true'
- name: NX_BRANCH
\${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
value: $(System.PullRequest.PullRequestNumber) # Pull request Number
\${{ if ne(variables['Build.Reason'], 'PullRequest') }}:
value: $(Build.SourceBranchName)
- name: TARGET_BRANCH
\${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
value: $[replace(variables['System.PullRequest.TargetBranch'],'refs/heads/','origin/')]
- name: BASE_SHA
\${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
value: $(git merge-base $(TARGET_BRANCH) HEAD)
\${{ if ne(variables['Build.Reason'], 'PullRequest') }}:
value: $(git rev-parse HEAD~1)
jobs:
- job: agent
displayName: Nx-Cloud agent
pool:
vmImage: 'ubuntu-latest'
strategy:
parallel: 4
steps:
- script: yarn --frozen-lockfile
displayName: NPM Install Dependencies
- script: npx nx-cloud start-agent
displayName: Start Nx-Cloud agent
- job: main
pool:
vmImage: 'ubuntu-latest'
steps:
- script: yarn --frozen-lockfile
displayName: NPM Install Dependencies
- script: yarn nx affected --target=lint --parallel=3
- script: yarn nx affected --target=build --parallel=3
- script: yarn nx affected --target=test --parallel=2
- script: yarn nx-cloud stop-all-agents
condition: always()
displayName: Stop all Nx-Cloud agents"
`;

exports[`lib should generate circleci CI config 1`] = `
"version: 2.1
orbs:
nx: nrwl/nx@1.3.0
jobs:
agent:
docker:
- image: cimg/node:lts-browsers
parameters:
ordinal:
type: integer
steps:
- checkout
- run:
name: Install dependencies
command: yarn --frozen-lockfile
- run:
name: Start the agent << parameters.ordinal >>
command: yarn nx-cloud start-agent
no_output_timeout: 60m
main:
docker:
- image: cimg/node:lts-browsers
environment:
NX_CLOUD_DISTRIBUTED_EXECUTION: 'true'
steps:
- checkout
- run:
name: Install dependencies
command: yarn --frozen-lockfile
- nx/set-shas:
main-branch-name: 'main'
- run:
name: Run lint
command: yarn nx affected --base=$NX_BASE --head=$NX_HEAD --target=lint --parallel=3
- run:
name: Run build
command: yarn nx affected --base=$NX_BASE --head=$NX_HEAD --target=build --parallel=3
- run:
name: Run test
command: yarn nx affected --base=$NX_BASE --head=$NX_HEAD --target=test --parallel=2
- run:
name: Stop all agents
command: yarn nx-cloud stop-all-agents
workflows:
build:
jobs:
- agent:
matrix:
parameters:
ordinal: [1, 2, 3]
- main"
`;
exports[`lib should generate github CI config 1`] = `
"name: build
on:
push:
branches:
- main
pull_request:
env:
NX_CLOUD_DISTRIBUTED_EXECUTION: true
NX_BRANCH: \${{ github.event.number || github.ref_name }}
jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Derive appropriate SHAs for base and head for \`nx affected\` commands
uses: nrwl/nx-set-shas@v2
with:
main-branch-name: 'main'
- uses: actions/setup-node@v1
with:
node-version: '16'
- run: yarn --frozen-lockfile
- name: Initialize the Nx Cloud distributed CI run
run: yarn nx-cloud start-ci-run
- run: yarn nx affected --target=lint --parallel=3
- run: yarn nx affected --target=build --parallel=3
- run: yarn nx affected --target=test --parallel=2
- name: Stop all running agents for this CI run
if: \${{ always() }}
run: yarn nx-cloud stop-all-agents
agents:
runs-on: ubuntu-latest
name: Agent \${{ matrix.agent }}
strategy:
matrix:
agent:
- [\\"1\\", \\"2\\", \\"3\\"]
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- uses: actions/setup-node@v1
with:
node-version: '16'
- run: yarn --frozen-lockfile
- name: Start Nx Agent \${{ matrix.agent }}
run: yarn nx-cloud start-agent"
`;
29 changes: 29 additions & 0 deletions packages/workspace/src/generators/ci-workflow/ci-workflow.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Tree } from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import { ciWorkflowGenerator } from './ci-workflow';

describe('lib', () => {
let tree: Tree;

beforeEach(() => {
tree = createTreeWithEmptyWorkspace();
});

it('should generate github CI config', async () => {
await ciWorkflowGenerator(tree, { ci: 'github' });

expect(tree.read('.github/workflows/build.yml', 'utf-8')).toMatchSnapshot();
});

it('should generate circleci CI config', async () => {
await ciWorkflowGenerator(tree, { ci: 'circleci' });

expect(tree.read('.circleci/config.yml', 'utf-8')).toMatchSnapshot();
});

it('should generate azure CI config', async () => {
await ciWorkflowGenerator(tree, { ci: 'azure' });

expect(tree.read('azure-pipelines.yml', 'utf-8')).toMatchSnapshot();
});
});
39 changes: 36 additions & 3 deletions packages/workspace/src/generators/ci-workflow/ci-workflow.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,43 @@
import { Tree } from '@nrwl/devkit';
import {
Tree,
names,
generateFiles,
joinPathFragments,
detectPackageManager,
getPackageManagerCommand,
} from '@nrwl/devkit';
import { deduceDefaultBase } from '../../utilities/default-base';

export interface Schema {
name?: string;
ci: 'github' | 'azure' | 'circleci';
}

export async function ciWorkflowGenerator(tree: Tree, options: Schema) {
// TODO: Implement
export async function ciWorkflowGenerator(host: Tree, schema: Schema) {
const ci = schema.ci;
const options = normalizeOptions(schema);

generateFiles(host, joinPathFragments(__dirname, 'files', ci), '', options);
// TODO: Implement error handling when file already exists
}

interface Substitutes {
mainBranch: string;
workflowName: string;
packageManagerInstall: string;
packageManagerPrefix: string;
tmpl: '';
}

function normalizeOptions(options: Schema): Substitutes {
const { name: workflowName } = names(options.name || 'build');
const { exec: packageManagerPrefix, ciInstall: packageManagerInstall } =
getPackageManagerCommand();
return {
workflowName,
packageManagerInstall,
packageManagerPrefix,
mainBranch: deduceDefaultBase(),
tmpl: '',
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: <%= workflowName %>

trigger:
- <%= mainBranch %>
pr:
- <%= mainBranch %>

variables:
- name: NX_CLOUD_DISTRIBUTED_EXECUTION
value: 'true'
- name: NX_DISTRIBUTED_TASK_EXECUTION_AGENT_COUNT
value: 4
- name: NX_VERBOSE_LOGGING
value: 'true'
- name: NX_BRANCH
${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
value: $(System.PullRequest.PullRequestNumber) # Pull request Number
${{ if ne(variables['Build.Reason'], 'PullRequest') }}:
value: $(Build.SourceBranchName)
- name: TARGET_BRANCH
${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
value: $[replace(variables['System.PullRequest.TargetBranch'],'refs/heads/','origin/')]
- name: BASE_SHA
${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
value: $(git merge-base $(TARGET_BRANCH) HEAD)
${{ if ne(variables['Build.Reason'], 'PullRequest') }}:
value: $(git rev-parse HEAD~1)

jobs:
- job: agent
displayName: Nx-Cloud agent
pool:
vmImage: 'ubuntu-latest'
strategy:
parallel: 4
steps:
- script: <%= packageManagerInstall %>
displayName: NPM Install Dependencies
- script: npx nx-cloud start-agent
displayName: Start Nx-Cloud agent

- job: main
pool:
vmImage: 'ubuntu-latest'
steps:
- script: <%= packageManagerInstall %>
displayName: NPM Install Dependencies
- script: <%= packageManagerPrefix %> nx affected --target=lint --parallel=3
- script: <%= packageManagerPrefix %> nx affected --target=build --parallel=3
- script: <%= packageManagerPrefix %> nx affected --target=test --parallel=2
- script: <%= packageManagerPrefix %> nx-cloud stop-all-agents
condition: always()
displayName: Stop all Nx-Cloud agents
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
version: 2.1

orbs:
nx: nrwl/nx@1.3.0

jobs:
agent:
docker:
- image: cimg/node:lts-browsers
parameters:
ordinal:
type: integer
steps:
- checkout
- run:
name: Install dependencies
command: <%= packageManagerInstall %>
- run:
name: Start the agent << parameters.ordinal >>
command: <%= packageManagerPrefix %> nx-cloud start-agent
no_output_timeout: 60m
main:
docker:
- image: cimg/node:lts-browsers
environment:
NX_CLOUD_DISTRIBUTED_EXECUTION: 'true'
steps:
- checkout
- run:
name: Install dependencies
command: <%= packageManagerInstall %>
- nx/set-shas:
main-branch-name: '<%= mainBranch %>'
- run:
name: Run lint
command: <%= packageManagerPrefix %> nx affected --base=$NX_BASE --head=$NX_HEAD --target=lint --parallel=3
- run:
name: Run build
command: <%= packageManagerPrefix %> nx affected --base=$NX_BASE --head=$NX_HEAD --target=build --parallel=3
- run:
name: Run test
command: <%= packageManagerPrefix %> nx affected --base=$NX_BASE --head=$NX_HEAD --target=test --parallel=2
- run:
name: Stop all agents
command: <%= packageManagerPrefix %> nx-cloud stop-all-agents

workflows:
<%= workflowName %>:
jobs:
- agent:
matrix:
parameters:
ordinal: [1, 2, 3]
- main

0 comments on commit deb348e

Please sign in to comment.