Skip to content

Commit

Permalink
Adds workflow:create command (#2678)
Browse files Browse the repository at this point in the history
# Why

Adds `eas workflow:create` to make it faster to create workflow files in a project. This command creates a file like **.eas/workflows/workflow.yml**. The user can choose the file name or can provide it as an arugment.

# Screenshots

<img width="552" alt="Screenshot 2024-11-08 at 8 50 58 AM" src="https://github.com/user-attachments/assets/5cf82e7e-cce6-4098-b291-fccdac25f103">
<img width="584" alt="Screenshot 2024-11-08 at 8 51 27 AM" src="https://github.com/user-attachments/assets/d6f6e7cb-18c1-420e-b52a-5bdd42446715">
<img width="617" alt="Screenshot 2024-11-08 at 8 52 04 AM" src="https://github.com/user-attachments/assets/81cc79cf-afb7-4855-bfce-0679f98655fa">

# Test Plan

Make sure that you can run the command as pictured above and that it correctly creates the workflow file. Also make sure that the unit tests pass.

# Future

Once we have docs for workflows that are public, I'd like to put a link to the docs in the default file this command creates. For now, I am just putting Hello World as a reasonable placeholder.

Co-authored-by: Szymon Dziedzic <[email protected]>
Co-authored-by: Stanisław Chmiela <[email protected]>
  • Loading branch information
3 people authored Nov 18, 2024
1 parent c7cfcaf commit 4571910
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 0 deletions.
121 changes: 121 additions & 0 deletions packages/eas-cli/src/commands/workflow/create.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import chalk from 'chalk';
import fs from 'fs/promises';
import fsExtra from 'fs-extra';
import path from 'path';
import prompts from 'prompts';

import EasCommand from '../../commandUtils/EasCommand';
import { EASNonInteractiveFlag } from '../../commandUtils/flags';
import Log from '../../log';
import { WorkflowFile } from '../../utils/workflowFile';

const DEFAULT_WORKFLOW_NAME = 'workflow.yml';
const HELLO_WORLD_TEMPLATE = `name: Hello World
on:
push:
branches: ['*']
jobs:
hello_world:
steps:
- uses: eas/checkout
- run: echo "Hello, World"
`;

export class WorkflowCreate extends EasCommand {
static override description = 'create a new workflow configuration YAML file';

static override args = [
{
name: 'name',
description: 'Name of the workflow file (must end with .yml or .yaml)',
required: false,
},
];

static override flags = {
...EASNonInteractiveFlag,
};

static override contextDefinition = {
...this.ContextOptions.ProjectDir,
};

async runAsync(): Promise<void> {
const {
args: { name: argFileName },
flags,
} = await this.parse(WorkflowCreate);

const { projectDir } = await this.getContextAsync(WorkflowCreate, {
nonInteractive: flags['non-interactive'],
});

let fileName = argFileName;

if (!fileName) {
const response = await prompts({
type: 'text',
name: 'fileName',
message: 'What would you like to name your workflow file?',
initial: DEFAULT_WORKFLOW_NAME,
validate: value => {
try {
WorkflowFile.validateYamlExtension(value);
return true;
} catch (error) {
return error instanceof Error ? error.message : 'Invalid file name';
}
},
});

if (!response.fileName) {
Log.warn('Workflow creation cancelled.');
process.exit(0);
}

fileName = response.fileName;
}

try {
await this.ensureWorkflowsDirectoryExistsAsync({ projectDir });
await this.createWorkflowFileAsync({ fileName, projectDir });
} catch (error) {
Log.error('Failed to create workflow file.');
throw error;
}
}

private async ensureWorkflowsDirectoryExistsAsync({
projectDir,
}: {
projectDir: string;
}): Promise<void> {
try {
await fs.access(path.join(projectDir, '.eas', 'workflows'));
} catch {
await fs.mkdir(path.join(projectDir, '.eas', 'workflows'), { recursive: true });
Log.withTick(`Created directory ${chalk.bold(path.join(projectDir, '.eas', 'workflows'))}`);
}
}

private async createWorkflowFileAsync({
fileName,
projectDir,
}: {
fileName: string;
projectDir: string;
}): Promise<void> {
WorkflowFile.validateYamlExtension(fileName);

const filePath = path.join(projectDir, '.eas', 'workflows', fileName);

if (await fsExtra.pathExists(filePath)) {
throw new Error(`Workflow file already exists: ${filePath}`);
}

await fs.writeFile(filePath, HELLO_WORLD_TEMPLATE);
Log.withTick(`Created ${chalk.bold(filePath)}`);
}
}
7 changes: 7 additions & 0 deletions packages/eas-cli/src/utils/workflowFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,11 @@ export namespace WorkflowFile {
);
}
}

export function validateYamlExtension(fileName: string): void {
const fileExtension = path.extname(fileName).toLowerCase();
if (fileExtension !== '.yml' && fileExtension !== '.yaml') {
throw new Error('File must have a .yml or .yaml extension');
}
}
}

0 comments on commit 4571910

Please sign in to comment.