Skip to content

Commit

Permalink
Added cake frosting switch
Browse files Browse the repository at this point in the history
Added Test for csproj-path parameter


Added tests for cake frosting project and index.js updated
  • Loading branch information
louisfischer authored and devlead committed Mar 19, 2024
1 parent 1223b6f commit 5b75644
Show file tree
Hide file tree
Showing 8 changed files with 190 additions and 29 deletions.
30 changes: 25 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![GitHub Marketplace](https://img.shields.io/github/v/release/cake-build/cake-action?label=Marketplace&sort=semver)](https://github.com/marketplace/actions/cake-action) [![GitHub Actions Build](https://github.com/cake-build/cake-action/workflows/Build/badge.svg)](https://github.com/cake-build/cake-action/actions?workflow=Build) [![GitHub Actions Tests](https://github.com/cake-build/cake-action/workflows/Tests/badge.svg)](https://github.com/cake-build/cake-action/actions?workflow=Tests) [![Coveralls](https://coveralls.io/repos/github/cake-build/cake-action/badge.svg?branch=master)](https://coveralls.io/github/cake-build/cake-action?branch=master)

This action allows you to run a Cake script from your GitHub Actions workflow without having to use a [bootstrapper](https://github.com/cake-build/resources).
This action allows you to run a Cake script or Cake Frosting project from your GitHub Actions workflow without having to use a [bootstrapper](https://github.com/cake-build/resources).

## Usage

Expand All @@ -14,7 +14,9 @@ steps:
uses: cake-build/cake-action@v2
```
The Cake action will look for a script named `build.cake` in your repository's root directory and run it for you using the [Cake Tool](https://www.nuget.org/packages/Cake.Tool/). All output from the Cake script will be automatically redirected to the build log for inspection.
The Cake action will look for a script named `build.cake` in your repository's root directory and run it for you using the [Cake Tool](https://www.nuget.org/packages/Cake.Tool/). If you are using a [Cake Frosting](https://cakebuild.net/docs/running-builds/runners/cake-frosting) project, the `csproj-path` parameter must be specified and the `script-path` is ignored.

All output from the Cake script or Cake Frosting project will be automatically redirected to the build log for inspection.

## Inputs

Expand All @@ -30,9 +32,21 @@ steps:
script-path: path/to/script.cake
```

### `csproj-path`

If you are using [Cake Frosting](https://cakebuild.net/docs/running-builds/runners/cake-frosting), you can specify the path with the `csproj-path` [input parameter](https://help.github.com/en/github/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idstepswith):

```yml
steps:
- name: Run Cake Frosting
uses: cake-build/cake-action@v2
with:
csproj-path: ./path/to/build.csproj
```

### `target`

You'll likely want to specify which task to run out of the ones defined in the Cake script. For that, you can use the `target` parameter:
You'll likely want to specify which task to run out of the ones defined in the Cake script or Cake Frosting project. For that, you can use the `target` parameter:

```yml
steps:
Expand Down Expand Up @@ -88,7 +102,11 @@ The arguments are defined in a [multi-line string literal](https://yaml.org/spec

### `cake-version`

By default, the Cake action will run your script using the latest _stable_ version of the [Cake .NET Core Global tool](https://www.nuget.org/packages/Cake.Tool/). However, if for some reason you want to [use a specific version of Cake](https://cakebuild.net/docs/tutorials/pinning-cake-version) (for compatibility with older third-party addins, for example), you can do so by specifying the version number in the `cake-version` parameter:
By default, the Cake action will run your script using the latest _stable_ version of the [Cake .NET Core Global tool](https://www.nuget.org/packages/Cake.Tool/).

_Ignored_ for Cake Frosting Project.

If for some reason you want to [use a specific version of Cake](https://cakebuild.net/docs/tutorials/pinning-cake-version) (for compatibility with older third-party addins, for example), you can do so by specifying the version number in the `cake-version` parameter.:

```yml
steps:
Expand All @@ -112,6 +130,8 @@ steps:

As of [Cake 1.0.0](https://github.com/cake-build/cake/releases/tag/v1.0.0), any [custom modules](https://cakebuild.net/docs/fundamentals/modules) that you reference in your script are [bootstrapped automatically](https://github.com/cake-build/cake/issues/2833) upon running it.

_Ignored_ for Cake Frosting Project.

If you're using an older version of Cake, however, you need to explicitly [bootstrap](https://cakebuild.net/docs/fundamentals/preprocessor-directives#module-directive) them before running the script. The Cake action can take care of this extra step for you by setting the `cake-bootstrap` parameter to `explicit`:

```yml
Expand All @@ -137,7 +157,7 @@ The default value is `auto`, which means that the modules will be automatically

## Cross-platform

Since the [Cake Tool](https://www.nuget.org/packages/Cake.Tool/) is built on .NET Core, the Cake action will run on any of the [virtual environments](https://help.github.com/en/github/automating-your-workflow-with-github-actions/software-in-virtual-environments-for-github-actions) supported by GitHub Actions, namely Linux, Windows and macOS.
Since the [Cake Tool](https://www.nuget.org/packages/Cake.Tool/) and [Cake Frosting](https://www.nuget.org/packages/Cake.Frosting) are built on .NET Core, the Cake action will run on any of the [virtual environments](https://help.github.com/en/github/automating-your-workflow-with-github-actions/software-in-virtual-environments-for-github-actions) supported by GitHub Actions, namely Linux, Windows and macOS.

This allows you to define your build step exactly _once_ and run it on multiple operating systems _in parallel_ by defining a [build matrix](https://help.github.com/en/github/automating-your-workflow-with-github-actions/configuring-a-workflow#configuring-a-build-matrix):

Expand Down
64 changes: 61 additions & 3 deletions __tests__/cake.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import * as path from 'path';
import { exec } from '@actions/exec';
import { which } from '@actions/io';
import * as path from 'path';

import * as cake from '../src/cake';
import { ToolsDirectory } from '../src/toolsDirectory';
import { CakeToolSettings } from '../src/cakeToolSettings';
import { CakeArgument, CakeSwitch } from '../src/cakeParameter';
import { CakeToolSettings } from '../src/cakeToolSettings';
import { ToolsDirectory } from '../src/toolsDirectory';

const pathToLocalToolsDirectory = path.join('path', 'to', 'tool');
const pathToLocalTool = path.join(pathToLocalToolsDirectory, 'dotnet-cake');
const dotnetManifestCake = 'dotnet tool run dotnet-cake';
const pathToCsprojFile = path.join('build', 'Build.csproj');
const dotnetRun = 'dotnet run';

jest.mock('@actions/exec');
jest.mock('@actions/io');
Expand Down Expand Up @@ -190,3 +193,58 @@ describe('When running a script successfully using the tool manifest', () => {
['script.cake', '--switch']);
});
});

describe('When running a Cake Frosting project successfully', () => {
const fakeExec = exec as jest.MockedFunction<typeof exec>;
const fakeToolsDirectory = new ToolsDirectory();

beforeAll(async () => {
fakeExec.mockReturnValue(Promise.resolve(0));
});

test('it should run with the default non-required parameters', async () => {
await cake.runProject(pathToCsprojFile, fakeToolsDirectory);

expect(fakeExec).toHaveBeenCalledWith(
dotnetRun,
[
'--project', pathToCsprojFile,
'--no-launch-profile',
'--verbosity', 'minimal',
'--configuration', 'Release',
`--paths_tools="${fakeToolsDirectory.path}"`
]);
});

test('it should run with the specified parameters', async () => {
await cake.runProject(
pathToCsprojFile,
fakeToolsDirectory,
new CakeArgument('param', 'arg'),
new CakeSwitch('switch'));

expect(fakeExec).toHaveBeenCalledWith(
dotnetRun,
[
'--project', pathToCsprojFile,
'--no-launch-profile',
'--verbosity', 'minimal',
'--configuration', 'Release',
`--paths_tools="${fakeToolsDirectory.path}"`,
'--param=arg',
'--switch'
]);
});
});

describe('When failing to run a Cake Frosting Project', () => {
const fakeExec = exec as jest.MockedFunction<typeof exec>;

beforeAll(() => {
fakeExec.mockReturnValue(Promise.resolve(-21));
});

test('it should throw error when csproj-path does not exist', async () => {
await expect(cake.runProject('', new ToolsDirectory())).rejects.toThrow('-21');
});
});
22 changes: 22 additions & 0 deletions __tests__/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,28 @@ describe('When running the action with the script path input argument', () => {
});
});

describe('When running the action with the csproj path input argument', () => {
const fakeGetInputs = action.getInputs as jest.MockedFunction<typeof action.getInputs>;
const fakeRunProject = cake.runProject as jest.MockedFunction<typeof cake.runProject>;

beforeAll(() => {
fakeGetInputs.mockReturnValue({
csprojPath: './path/to/build.csproj',
scriptArguments: []
});
});

test('it should run the Cake Frosting Project', async () => {
await run();
expect(cake.runProject).toHaveBeenCalled();
});

test('it should run the specified Cake Frosting project', async () => {
await run();
expect(fakeRunProject.mock.calls[0][0]).toBe('./path/to/build.csproj');
});
});

describe('When running the action with tool-manifest as the Cake version input argument', () => {
const fakeGetInputs = action.getInputs as jest.MockedFunction<typeof action.getInputs>;
const fakeInstallCakeTool = cakeTool.install as jest.MockedFunction<typeof cakeTool.install>;
Expand Down
5 changes: 4 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: 'Cake Action'
description: 'Run a Cake script as part of your build.'
description: 'Run a Cake script or Cake Frosting project as part of your build.'
author: 'Enrico Campidoglio'
branding:
icon: 'box'
Expand All @@ -9,6 +9,9 @@ inputs:
description: 'The path of the Cake script to run.'
required: false
default: 'build.cake'
csproj-path:
description: 'The path of the Cake Frosting Project to run. Takes precedence over script-path'
required: false
target:
description: 'The name of the task to execute. Note that this argument must be supported by the script.'
required: false
Expand Down
45 changes: 35 additions & 10 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3991,6 +3991,7 @@ const input = __importStar(__nccwpck_require__(6747));
function getInputs() {
return {
scriptPath: core.getInput('script-path'),
csprojPath: core.getInput('csproj-path'),
cakeVersion: getCakeVersionInput(),
cakeBootstrap: getCakeBootstrapInput(),
scriptArguments: getScriptInputs()
Expand Down Expand Up @@ -4070,11 +4071,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.bootstrapScript = exports.runScript = void 0;
exports.bootstrapScript = exports.runProject = exports.runScript = void 0;
const exec_1 = __nccwpck_require__(1514);
const io_1 = __nccwpck_require__(7436);
const dotnetCake = 'dotnet-cake';
const dotnetLocalToolCake = 'dotnet tool run dotnet-cake';
const dotnetRun = 'dotnet run';
function runScript(scriptPath = 'build.cake', cakeToolSettings, ...params) {
return __awaiter(this, void 0, void 0, function* () {
const cakeToolPath = yield resolveCakeToolPath(cakeToolSettings);
Expand All @@ -4086,6 +4088,23 @@ function runScript(scriptPath = 'build.cake', cakeToolSettings, ...params) {
});
}
exports.runScript = runScript;
function runProject(csprojPath, toolsDir, ...params) {
return __awaiter(this, void 0, void 0, function* () {
const cakeParams = formatParameters(params);
const exitCode = yield (0, exec_1.exec)(dotnetRun, [
'--project', csprojPath,
'--no-launch-profile',
'--verbosity', 'minimal',
'--configuration', 'Release',
`--paths_tools="${toolsDir}"`,
...cakeParams
]);
if (exitCode != 0) {
throw new Error(`Failed to run the csproj. Exit code: ${exitCode}`);
}
});
}
exports.runProject = runProject;
function bootstrapScript(scriptPath = 'build.cake', cakeToolSettings) {
return __awaiter(this, void 0, void 0, function* () {
const cakeToolPath = yield resolveCakeToolPath(cakeToolSettings);
Expand Down Expand Up @@ -4435,30 +4454,36 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.run = void 0;
const core = __importStar(__nccwpck_require__(2186));
const toolsDirectory_1 = __nccwpck_require__(6745);
const action = __importStar(__nccwpck_require__(7672));
const cake = __importStar(__nccwpck_require__(9275));
const cakeTool = __importStar(__nccwpck_require__(4574));
const cakeToolSettings_1 = __nccwpck_require__(6881);
const guards_1 = __nccwpck_require__(3265);
const dotnet = __importStar(__nccwpck_require__(9870));
const cakeTool = __importStar(__nccwpck_require__(4574));
const cake = __importStar(__nccwpck_require__(9275));
const action = __importStar(__nccwpck_require__(7672));
const guards_1 = __nccwpck_require__(3265);
const toolsDirectory_1 = __nccwpck_require__(6745);
function run() {
return __awaiter(this, void 0, void 0, function* () {
try {
const inputs = action.getInputs();
const scriptPath = inputs.scriptPath;
const csprojPath = inputs.csprojPath;
const version = inputs.cakeVersion;
const bootstrap = inputs.cakeBootstrap;
const toolsDir = new toolsDirectory_1.ToolsDirectory();
toolsDir.create();
const cakeToolSettings = new cakeToolSettings_1.CakeToolSettings(toolsDir, (version === null || version === void 0 ? void 0 : version.version) === 'tool-manifest');
dotnet.disableTelemetry();
dotnet.disableWelcomeMessage();
yield cakeTool.install(toolsDir, version);
if (bootstrap === 'explicit') {
yield cake.bootstrapScript(scriptPath, cakeToolSettings);
if (!csprojPath) {
yield cakeTool.install(toolsDir, version);
if (bootstrap === 'explicit') {
yield cake.bootstrapScript(scriptPath, cakeToolSettings);
}
yield cake.runScript(scriptPath, cakeToolSettings, ...inputs.scriptArguments);
}
else {
yield cake.runProject(csprojPath, toolsDir, ...inputs.scriptArguments);
}
yield cake.runScript(scriptPath, cakeToolSettings, ...inputs.scriptArguments);
}
catch (error) {
if ((0, guards_1.isError)(error)) {
Expand Down
3 changes: 3 additions & 0 deletions src/action.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import * as core from '@actions/core';

import * as script from './cakeParameter';
import * as input from './input';

interface CakeInputs {
readonly scriptPath?: string,
readonly csprojPath?: string,
readonly cakeVersion?: CakeVersion,
readonly cakeBootstrap?: CakeBootstrap;
}
Expand Down Expand Up @@ -35,6 +37,7 @@ export type CakeBootstrap =
export function getInputs(): CakeInputs & ScriptInputs {
return {
scriptPath: core.getInput('script-path'),
csprojPath: core.getInput('csproj-path'),
cakeVersion: getCakeVersionInput(),
cakeBootstrap: getCakeBootstrapInput(),
scriptArguments: getScriptInputs()
Expand Down
25 changes: 24 additions & 1 deletion src/cake.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { exec } from '@actions/exec';
import { which } from '@actions/io';
import { CakeToolSettings } from './cakeToolSettings';

import { CakeParameter } from './cakeParameter';
import { CakeToolSettings } from './cakeToolSettings';
import { ToolsDirectory } from './toolsDirectory';

const dotnetCake = 'dotnet-cake';
const dotnetLocalToolCake = 'dotnet tool run dotnet-cake';
const dotnetRun = 'dotnet run';

export async function runScript(
scriptPath = 'build.cake',
Expand All @@ -20,6 +23,26 @@ export async function runScript(
}
}

export async function runProject(
csprojPath: string,
toolsDir: ToolsDirectory,
...params: CakeParameter[]
) {
const cakeParams = formatParameters(params);
const exitCode = await exec(dotnetRun, [
'--project', csprojPath,
'--no-launch-profile',
'--verbosity', 'minimal',
'--configuration', 'Release',
`--paths_tools="${toolsDir}"`,
...cakeParams
]);

if (exitCode != 0) {
throw new Error(`Failed to run the csproj. Exit code: ${exitCode}`);
}
}

export async function bootstrapScript(
scriptPath = 'build.cake',
cakeToolSettings?: CakeToolSettings
Expand Down
Loading

0 comments on commit 5b75644

Please sign in to comment.