Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Issue #30] Set up CI/CD for CLI #74

Merged
merged 10 commits into from
Feb 6, 2025
38 changes: 38 additions & 0 deletions .github/workflows/cd-cli-npm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: CD - Publish @common-grants/cli

on:
push:
branches:
- main
paths:
- "cli/**" # Trigger only if files in the `cli/` directory are changed
- ".github/workflows/cd-cli-npm.yml"

defaults:
run:
working-directory: ./cli

jobs:
publish:
runs-on: ubuntu-latest

steps:
- name: Check out code
uses: actions/checkout@v4

- name: Install dependencies
run: npm ci

# Setup .npmrc file to publish to npm
- uses: actions/setup-node@v4
with:
node-version: "20.x"
registry-url: "https://registry.npmjs.org"

- name: Run checks
run: npm run checks

- name: Publish to npm
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npm publish --tag alpha --access public
35 changes: 35 additions & 0 deletions .github/workflows/ci-cli-npm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: CI - Publish @common-grants/cli (dry run)

on:
pull_request:
branches:
- main
paths:
- "cli/**" # Trigger only if files in the `cli/` directory are changed
- ".github/workflows/ci-cli-npm.yml"

defaults:
run:
working-directory: ./cli

jobs:
publish:
runs-on: ubuntu-latest

steps:
- name: Check out code
uses: actions/checkout@v4

- name: Install dependencies
run: npm ci

# Setup .npmrc file to publish to npm
- uses: actions/setup-node@v4
with:
node-version: "20.x"
registry-url: "https://registry.npmjs.org"

- name: Dry run publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npm publish --tag alpha --access public --dry-run
248 changes: 88 additions & 160 deletions cli/README.md
Original file line number Diff line number Diff line change
@@ -1,224 +1,152 @@
# CommonGrants CLI

The CommonGrants CLI is a tool for working with the CommonGrants protocol. It's designed to simplify the process of defining, implementing, and validating CommonGrants APIs.
The CommonGrants CLI (`cg`) is a tool for working with the CommonGrants protocol. It simplifies the process of defining, implementing, and validating CommonGrants APIs.

## Initializing a project
> **Note**: This package is currently in alpha. The commands described below are mocked implementations that will be replaced with full functionality in future releases.

### User story

As a developer implementing the CommonGrants protocol from scratch, I want to run a command that quickly sets up a new API, custom fields library, or other CommonGrants package, so that I don't have to spend a lot of time creating boilerplate code.

### Developer experience

Simplest use case: Developer runs `cg init` and is prompted to select from a list of templates.
## Installation

```bash
cg init
```

#### Additional Features
- Pass a `--template` flag to create a project using a predefined CommonGrants template.
- Use `--dir` to specify a target directory for the generated project.
- Run `cg init --list` to display available templates without starting initialization.

#### Example Usage
```bash
# Initialize a new project interactively
cg init

# Initialize a new project using a specific template
cg init --template grants-api

# Initialize a new project in a custom directory
cg init --template grants-api --dir ./my-grants-project
# Install globally
npm install -g @common-grants/cli

# List available templates before choosing one
cg init --list
# Or use with npx
npx @common-grants/cli <command>
```

### Technical details
- If the user doesn't pass a `--template` flag to the command, it should prompt users with a list of optional templates.
- This command should be a thin wrapper for the `tsp init` function so that users can also pass paths or URLs to valid TypeSpec templates to create their own templates.

---

## Previewing an OpenAPI spec

### User story
## Usage

As a developer working on a CommonGrants API, I want to preview my OpenAPI specification using Swagger or Redocly, so that I can quickly inspect my API documentation.

### Developer experience

Simplest use case: Preview an OpenAPI spec in Swagger UI.
View available commands and options:

```bash
cg preview spec <path-to-typespec>
cg --help
```

#### Additional Features
- Allow choosing a preview tool (`--ui swagger` or `--ui redocly`).
- Open a local preview server for interactive exploration.
Output:

#### Example Usage
```bash
# Preview an OpenAPI spec with Swagger UI
cg preview spec grants-api.tsp --ui swagger

# Preview an OpenAPI spec with Redocly
cg preview spec grants-api.tsp --ui redocly
```
Usage: cg [options] [command]

### Technical details
- The command should generate an OpenAPI spec from the TypeSpec project and serve it using Swagger UI or Redocly.
- Defaults to Swagger UI if no `--ui` option is specified.

---

## Adding a custom field

### User story

As a developer defining a CommonGrants API, I want to add a new custom field with configurable options, so that I can extend the API schema easily.

### Developer experience
CommonGrants CLI tools

Simplest use case: Add a custom field by specifying `name` and `type`.
Options:
-V, --version output the version number
-h, --help display help for command

```bash
cg add field <name> <type>
Commands:
init [options] Initialize a new CommonGrants project
preview Preview an OpenAPI specification
add field Add a custom field to the schema
check Validate APIs and specifications
generate Generate server or client code
help [command] display help for command
```

#### Additional Features
- Provide an example value with `--example`.
- Add a description using `--description`.
## Development status

#### Example Usage
```bash
# Add a simple custom field
cg add field fundingAmount number
This CLI is currently in alpha stage with the following limitations:

# Add a custom field with an example value
cg add field fundingAmount number --example 100000
- All commands are mocked and return simulated responses

# Add a custom field with a description
cg add field fundingAmount number --description "The total amount of funding available"
```
The first round of releases will implement the following core:

### Technical details
- The command should append the new field to the appropriate schema definition in the TypeSpec project.
- If `--example` or `--description` is provided, they should be included as metadata in the schema definition.
- Basic project initialization
- Previewing an OpenAPI spec using Swagger UI or Redocly
- Validating an API specification against the CommonGrants standard

---
Subsequent releases will add:

## Validating a CommonGrants API implementation
- An expanded set of templates
- Validating an API implementation against its specification
- Generating server and client code

### User story
## Anticipated features

As a developer implementing a CommonGrants API, I want to run a command that checks whether a given API matches an OpenAPI spec, so that I can catch inconsistencies between the spec and the implementation.
The following examples describe the anticipated features of the CLI, but these are not yet implemented and are subject to change.

### Developer experience

```bash
cg check api <url-for-root-of-the-api> <path-to-typespec-or-open-api-spec>
```
### Initialize a Project

#### Additional Features
- Allow selecting the HTTP client for validation (e.g., `curl`, `httpx`).
- Provide an option to generate a report (`--report json` or `--report html`).
- Support authentication with `--auth` flag for APIs requiring credentials.
Create a new CommonGrants project from a template:

#### Example Usage
```bash
# Validate a running API against a spec
cg check api https://api.example.com grants-api.yaml
# Initialize interactively
cg init

# Validate using a different HTTP client
cg check api https://api.example.com grants-api.yaml --client httpx
# Use a specific template
cg init --template grants-api

# Validate an authenticated API
cg check api https://api.example.com grants-api.yaml --auth bearer:mytoken
# Initialize in a custom directory
cg init --template grants-api --dir ./my-grants-project

# Generate a validation report in JSON format
cg check api https://api.example.com grants-api.yaml --report json
# List available templates
cg init --list
```

### Technical details
- This command should leverage existing tools that validate OpenAPI spec implementations, where possible.
### Preview OpenAPI Specification

---
Preview an API specification using Swagger UI or Redocly:

## Generating server code
```bash
# Preview with Swagger UI (default)
cg preview spec.tsp

### User story
# Preview with Redocly
cg preview spec.tsp --ui redocly
```

As a developer implementing a CommonGrants API, I want to run a command that auto-generates an API server interface from a specification, so that I can follow a pattern of specification-driven development and quickly build APIs from scratch using the CommonGrants library.
### Add Custom Fields

### Developer experience
Extend the API schema with custom fields:

```bash
cg generate server <path-to-typespec>
# Add a basic field
cg add field fundingAmount number

# Include example and description
cg add field fundingAmount number --example 100000 --description "Total funding available"
```

#### Additional Features
- Allow specifying a language/framework with `--lang` (e.g., Python, Node.js).
- Enable plugin support for custom server code generation.
- Generate only specific components with `--only <controllers|models|routes>`.
### Validate API Implementation

Check if an API implementation matches its specification:

#### Example Usage
```bash
# Generate a server using the default framework
cg generate server grants-api.tsp
# Basic validation
cg check api https://api.example.com spec.yaml

# Generate a server for a specific language or framework
cg generate server grants-api.tsp --lang python
# Generate validation report
cg check api https://api.example.com spec.yaml --report json

# Generate only controllers and routes
cg generate server grants-api.tsp --only controllers,routes
# Validate with authentication
cg check api https://api.example.com spec.yaml --auth bearer:token
```

### Technical details
- This may require a combination of TypeSpec emitters and OpenAPI codegen.
- If an API framework isn't specified by the user via a flag, the CLI should prompt a user to choose one.
- Ideally, this entry point would be designed to support plugins for custom server code generators.
### Generate Server Code

---
Generate API server code from a specification:

## Generating client code

### User story

As a developer consuming a CommonGrants API, I want to run a command that generates client code from an API spec, so that I don't have to manually set up the code to work with that API.
```bash
# Generate with default settings
cg generate server spec.tsp

### Developer experience
# Specify language/framework
cg generate server spec.tsp --lang python

```bash
cg generate client <path-to-typespec>
# Generate specific components
cg generate server spec.tsp --only controllers,routes
```

#### Additional Features
- Support multiple output formats (`--output <path>`).
- Allow targeting specific programming languages (`--lang`).
- Optionally include API documentation with `--docs`.
### Generate Client Code

#### Example Usage
```bash
# Generate a client SDK from a spec
cg generate client grants-api.tsp
Generate client SDKs from an API specification:

# Generate a client SDK for TypeScript
cg generate client grants-api.tsp --lang typescript
```bash
# Generate default client
cg generate client spec.tsp

# Save generated client SDK in a custom directory
cg generate client grants-api.tsp --output ./sdk
# Generate for specific language
cg generate client spec.tsp --lang typescript

# Include API documentation
cg generate client grants-api.tsp --docs
# Include documentation
cg generate client spec.tsp --docs
```

### Technical details
- This may require a combination of TypeSpec emitters and OpenAPI codegen.
- If a client framework isn't specified by the user via a flag, the CLI should prompt a user to choose one.
- Ideally, this entry point would be designed to support plugins for custom client code generators.


2 changes: 1 addition & 1 deletion cli/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const config: Config = {
testEnvironment: "node",
testMatch: ["**/__tests__/**/*.test.ts"],
collectCoverage: true,
collectCoverageFrom: ["src/**/*.ts", "!src/index.ts", "!src/**/*.d.ts"],
collectCoverageFrom: ["src/**/*.ts", "!src/index.ts", "!src/**/*.d.ts", "!src/__tests__/**/*.ts"],
testPathIgnorePatterns: ["/node_modules/", "/__tests__/integration/"],
};

Expand Down
Loading