Skip to content

Commit

Permalink
feat(gradle): add ci-workflow generator
Browse files Browse the repository at this point in the history
  • Loading branch information
FrozenPandaz committed May 1, 2024
1 parent c09f70f commit 75b7634
Show file tree
Hide file tree
Showing 12 changed files with 379 additions and 0 deletions.
8 changes: 8 additions & 0 deletions docs/generated/manifests/menus.json
Original file line number Diff line number Diff line change
Expand Up @@ -7626,6 +7626,14 @@
"children": [],
"isExternal": false,
"disableCollapsible": false
},
{
"id": "ci-workflow",
"path": "/nx-api/gradle/generators/ci-workflow",
"name": "ci-workflow",
"children": [],
"isExternal": false,
"disableCollapsible": false
}
],
"isExternal": false,
Expand Down
9 changes: 9 additions & 0 deletions docs/generated/manifests/nx-api.json
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,15 @@
"originalFilePath": "/packages/gradle/src/generators/init/schema.json",
"path": "/nx-api/gradle/generators/init",
"type": "generator"
},
"/nx-api/gradle/generators/ci-workflow": {
"description": "Setup a CI Workflow to run Nx in CI",
"file": "generated/packages/gradle/generators/ci-workflow.json",
"hidden": false,
"name": "ci-workflow",
"originalFilePath": "/packages/gradle/src/generators/ci-workflow/schema.json",
"path": "/nx-api/gradle/generators/ci-workflow",
"type": "generator"
}
},
"path": "/nx-api/gradle"
Expand Down
9 changes: 9 additions & 0 deletions docs/generated/packages-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -1052,6 +1052,15 @@
"originalFilePath": "/packages/gradle/src/generators/init/schema.json",
"path": "gradle/generators/init",
"type": "generator"
},
{
"description": "Setup a CI Workflow to run Nx in CI",
"file": "generated/packages/gradle/generators/ci-workflow.json",
"hidden": false,
"name": "ci-workflow",
"originalFilePath": "/packages/gradle/src/generators/ci-workflow/schema.json",
"path": "gradle/generators/ci-workflow",
"type": "generator"
}
],
"githubRoot": "https://github.com/nrwl/nx/blob/master",
Expand Down
42 changes: 42 additions & 0 deletions docs/generated/packages/gradle/generators/ci-workflow.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"name": "ci-workflow",
"factory": "./src/generators/ci-workflow/generator",
"schema": {
"$schema": "https://json-schema.org/schema",
"$id": "NxGradleCiWorkflowSchema",
"title": "Gradle CI Workflow Generator",
"description": "Setup a CI Workflow to run Nx in CI.",
"type": "object",
"properties": {
"ci": {
"type": "string",
"description": "CI provider.",
"enum": ["github", "circleci"],
"x-prompt": {
"message": "What is your target CI provider?",
"type": "list",
"items": [
{ "value": "github", "label": "GitHub Actions" },
{ "value": "circleci", "label": "Circle CI" }
]
}
},
"name": {
"type": "string",
"description": "Workflow name.",
"$default": { "$source": "argv", "index": 0 },
"default": "CI",
"x-prompt": "How should we name your workflow?",
"pattern": "^[a-zA-Z].*$"
}
},
"required": ["ci", "name"],
"presets": []
},
"description": "Setup a CI Workflow to run Nx in CI",
"implementation": "/packages/gradle/src/generators/ci-workflow/generator.ts",
"aliases": [],
"hidden": false,
"path": "/packages/gradle/src/generators/ci-workflow/schema.json",
"type": "generator"
}
1 change: 1 addition & 0 deletions docs/shared/reference/sitemap.md
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@
- [Overview](/nx-api/gradle/documents/overview)
- [generators](/nx-api/gradle/generators)
- [init](/nx-api/gradle/generators/init)
- [ci-workflow](/nx-api/gradle/generators/ci-workflow)
- [jest](/nx-api/jest)
- [documents](/nx-api/jest/documents)
- [Overview](/nx-api/jest/documents/overview)
Expand Down
5 changes: 5 additions & 0 deletions packages/gradle/generators.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
"factory": "./src/generators/init/init#initGenerator",
"schema": "./src/generators/init/schema.json",
"description": "Initializes a Gradle project in the current workspace"
},
"ci-workflow": {
"factory": "./src/generators/ci-workflow/generator",
"schema": "./src/generators/ci-workflow/schema.json",
"description": "Setup a CI Workflow to run Nx in CI"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`ci-workflow generator circleci pipeline should match snapshot 1`] = `
"version: 2.1
orbs:
nx: nrwl/nx@1.6.2
jobs:
main:
environment:
# Configure the JVM and Gradle to avoid OOM errors
_JAVA_OPTIONS: '-Xmx3g'
GRADLE_OPTS: '-Dorg.gradle.daemon=false -Dorg.gradle.workers.max=2'
docker:
- image: cimg/openjdk:17.0-node
steps:
- checkout
# Connect your workspace on my.nx.app and uncomment this to enable task distribution.
# The "--stop-agents-after" is optional, but allows idle agents to shut down once the "build" targets have been requested
# - run: npx nx-cloud start-ci-run --distribute-on="5 linux-medium-jvm" --stop-agents-after="build"
- nx/set-shas:
main-branch-name: 'main'
# Required for nx affected if we're on a branch
- when:
condition: eq(variables['Build.Reason'], 'PullRequest')
steps:
- run: git branch --track main origin/main
- run: ./nx affected --base=$NX_BASE --head=$NX_HEAD -t test build
workflows:
version: 2
ci:
jobs:
- main
"
`;

exports[`ci-workflow generator github pipeline should match snapshot 1`] = `
"name: CI
on:
push:
branches:
- main
pull_request:
permissions:
actions: read
contents: read
jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
# Connect your workspace on my.nx.app and uncomment this to enable task distribution.
# The "--stop-agents-after" is optional, but allows idle agents to shut down once the "build" targets have been requested
# - run: npx nx-cloud start-ci-run --distribute-on="5 linux-medium-jvm" --stop-agents-after="build"
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
- uses: nrwl/nx-set-shas@v4
- run: git branch --track main origin/main
if: \${{ github.event_name == 'pull_request' }}
- run: ./nx affected -t test build
"
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
version: 2.1

orbs:
nx: nrwl/nx@1.6.2

jobs:
main:
environment:
# Configure the JVM and Gradle to avoid OOM errors
_JAVA_OPTIONS: "-Xmx3g"
GRADLE_OPTS: "-Dorg.gradle.daemon=false -Dorg.gradle.workers.max=2"
docker:
- image: cimg/openjdk:17.0-node
steps:
- checkout

# Connect your workspace on <%= nxCloudHost %> and uncomment this to enable task distribution.
# The "--stop-agents-after" is optional, but allows idle agents to shut down once the "build" targets have been requested
# - run: <%= packageManagerPrefix %> nx-cloud start-ci-run --distribute-on="5 linux-medium-jvm" --stop-agents-after="build"

- nx/set-shas:
main-branch-name: '<%= mainBranch %>'

<% for (const command of commands) { %>
- run: <%= command %><% } %>

workflows:
version: 2

<%= workflowFileName %>:
jobs:
- main
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: <%= workflowName %>

on:
push:
branches:
- <%= mainBranch %>
pull_request:

permissions:
actions: read
contents: read

jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

# Connect your workspace on <%= nxCloudHost %> and uncomment this to enable task distribution.
# The "--stop-agents-after" is optional, but allows idle agents to shut down once the "build" targets have been requested
# - run: <%= packageManagerPrefix %> nx-cloud start-ci-run --distribute-on="5 linux-medium-jvm" --stop-agents-after="build"

- name: Setup Gradle
uses: gradle/gradle-build-action@v2

- uses: nrwl/nx-set-shas@v4

- run: git branch --track main origin/main
if: ${{ github.event_name == 'pull_request' }}
<% for (const command of commands) { %>
- run: <%= command %><% } %>
35 changes: 35 additions & 0 deletions packages/gradle/src/generators/ci-workflow/generator.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import { Tree, updateJson, NxJsonConfiguration } from '@nx/devkit';

import { ciWorkflowGenerator } from './generator';

describe('ci-workflow generator', () => {
let tree: Tree;

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

beforeEach(() => {
updateJson<NxJsonConfiguration>(tree, 'nx.json', (json) => {
return {
...json,
nxCloudAccessToken: 'xxxx-xxx-xxxx',
nxCloudUrl: 'https://my.nx.app',
};
});
});

describe.each([
['github', '.github/workflows/ci.yml'],
['circleci', '.circleci/config.yml'],
] as const)(`%s pipeline`, (ciProvider, output) => {
it('should match snapshot', async () => {
await ciWorkflowGenerator(tree, {
name: 'CI',
ci: ciProvider,
});
expect(tree.read(output, 'utf-8')).toMatchSnapshot();
});
});
});
86 changes: 86 additions & 0 deletions packages/gradle/src/generators/ci-workflow/generator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import {
Tree,
names,
generateFiles,
getPackageManagerCommand,
NxJsonConfiguration,
formatFiles,
detectPackageManager,
readNxJson,
} from '@nx/devkit';
import { join } from 'path';
import { getNxCloudUrl, isNxCloudUsed } from 'nx/src/utils/nx-cloud-utils';
import { deduceDefaultBase } from 'nx/src/utils/default-base';

function getCiCommands(ci: Schema['ci'], mainBranch: string): string[] {
switch (ci) {
case 'circleci': {
return [`./nx affected --base=$NX_BASE --head=$NX_HEAD -t test build`];
}
default: {
return [`./nx affected -t test build`];
}
}
}

export interface Schema {
name: string;
ci: 'github' | 'circleci';
packageManager?: null;
commands?: string[];
}

export async function ciWorkflowGenerator(tree: Tree, schema: Schema) {
const ci = schema.ci;

const nxJson: NxJsonConfiguration = readNxJson(tree);
const nxCloudUsed = isNxCloudUsed(nxJson);
if (!nxCloudUsed) {
throw new Error('This workspace is not connected to Nx Cloud.');
}

const options = getTemplateData(schema, nxJson);
generateFiles(tree, join(__dirname, 'files', ci), '', options);
await formatFiles(tree);
}

interface Substitutes {
mainBranch: string;
workflowName: string;
workflowFileName: string;
packageManager: string;
packageManagerPrefix: string;
commands: string[];
nxCloudHost: string;
}

function getTemplateData(
options: Schema,
nxJson: NxJsonConfiguration
): Substitutes {
const { name: workflowName, fileName: workflowFileName } = names(
options.name
);
const packageManager = detectPackageManager();
const { exec: packageManagerPrefix } =
getPackageManagerCommand(packageManager);

const nxCloudUrl = getNxCloudUrl(nxJson);
const nxCloudHost = new URL(nxCloudUrl).host;

const mainBranch = deduceDefaultBase();

const commands = options.commands ?? getCiCommands(options.ci, mainBranch);

return {
workflowName,
workflowFileName,
packageManager,
packageManagerPrefix,
commands,
mainBranch,
nxCloudHost,
};
}

export default ciWorkflowGenerator;

0 comments on commit 75b7634

Please sign in to comment.