fix(obsidian-kb): restore files and shorten description
This commit is contained in:
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"registry": "https://clawhub.ai",
|
||||
"slug": "ci-gen",
|
||||
"installedVersion": "1.0.0",
|
||||
"installedAt": 1770282141006
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
# ai-ci
|
||||
|
||||
Setting up CI/CD from scratch is a pain. This tool looks at your project and generates the right GitHub Actions workflow for it.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm install -g ai-ci
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# Generate a GitHub Actions workflow
|
||||
npx ai-ci
|
||||
|
||||
# Specify provider and deploy target
|
||||
npx ai-ci --provider github --deploy vercel
|
||||
|
||||
# Preview without writing
|
||||
npx ai-ci --preview
|
||||
|
||||
# Different deploy targets
|
||||
npx ai-ci --deploy netlify
|
||||
npx ai-ci --deploy aws
|
||||
npx ai-ci --deploy docker
|
||||
```
|
||||
|
||||
## What it does
|
||||
|
||||
Scans your project to figure out the language, framework, test setup, and build steps. Then generates a proper CI/CD workflow with linting, testing, building, and deployment configured.
|
||||
|
||||
## Supported
|
||||
|
||||
- **Providers**: GitHub Actions (more coming)
|
||||
- **Deploy targets**: Vercel, Netlify, AWS, Docker, Fly.io, Railway
|
||||
- **Languages**: Node.js, Python, Go, Rust, Ruby, Java
|
||||
|
||||
## Requirements
|
||||
|
||||
Set your `OPENAI_API_KEY` environment variable.
|
||||
|
||||
```bash
|
||||
export OPENAI_API_KEY=sk-...
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
@@ -1,77 +0,0 @@
|
||||
---
|
||||
name: ci-gen
|
||||
description: Generate GitHub Actions CI/CD workflows from project analysis. Use when setting up automated pipelines.
|
||||
---
|
||||
|
||||
# CI/CD Workflow Generator
|
||||
|
||||
Point this at any project and get a working GitHub Actions workflow. It scans your codebase, detects the stack, and generates a pipeline that actually makes sense for your setup.
|
||||
|
||||
**One command. Zero config. Just works.**
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
npx ai-ci ./my-project
|
||||
```
|
||||
|
||||
## What It Does
|
||||
|
||||
- Scans your project to detect framework, language, and dependencies
|
||||
- Generates GitHub Actions workflow with proper build and test steps
|
||||
- Includes caching for faster CI runs
|
||||
- Sets up deployment steps based on common platforms
|
||||
- Creates separate workflows for PRs vs main branch pushes
|
||||
|
||||
## Usage Examples
|
||||
|
||||
```bash
|
||||
# Analyze current directory
|
||||
npx ai-ci .
|
||||
|
||||
# Generate for a specific project
|
||||
npx ai-ci ./apps/frontend
|
||||
|
||||
# Include deployment to Vercel
|
||||
npx ai-ci . --deploy vercel
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- **Review the output** - AI generates good defaults but tweak for your exact needs
|
||||
- **Start with tests only** - Get CI green first, add deployment later
|
||||
- **Use secrets properly** - The workflow references secrets, make sure to add them in GitHub
|
||||
- **Keep it simple** - Don't overcomplicate your first pipeline
|
||||
|
||||
## When to Use This
|
||||
|
||||
- Starting a new project and need CI fast
|
||||
- Migrating from another CI system to GitHub Actions
|
||||
- Learning GitHub Actions syntax through real examples
|
||||
- Standardizing CI across multiple repos
|
||||
|
||||
## Part of the LXGIC Dev Toolkit
|
||||
|
||||
This is one of 110+ free developer tools built by LXGIC Studios. No paywalls, no sign-ups, no API keys on free tiers. Just tools that work.
|
||||
|
||||
**Find more:**
|
||||
- GitHub: https://github.com/LXGIC-Studios
|
||||
- Twitter: https://x.com/lxgicstudios
|
||||
- Substack: https://lxgicstudios.substack.com
|
||||
- Website: https://lxgic.dev
|
||||
|
||||
## Requirements
|
||||
|
||||
No install needed. Just run with npx. Node.js 18+ recommended.
|
||||
|
||||
```bash
|
||||
npx ai-ci --help
|
||||
```
|
||||
|
||||
## How It Works
|
||||
|
||||
The tool uses glob patterns to scan your project structure. It identifies package.json, requirements.txt, Dockerfile, and other config files to understand your stack. Then it generates a workflow YAML tailored to what it found.
|
||||
|
||||
## License
|
||||
|
||||
MIT. Free forever. Use it however you want.
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"ownerId": "kn7as1q30eykdpxycyg4tp01n9802dwe",
|
||||
"slug": "ci-gen",
|
||||
"version": "1.0.0",
|
||||
"publishedAt": 1769626080933
|
||||
}
|
||||
Generated
-1316
File diff suppressed because it is too large
Load Diff
@@ -1,35 +0,0 @@
|
||||
{
|
||||
"name": "ai-ci",
|
||||
"version": "1.0.0",
|
||||
"description": "Generates GitHub Actions CI/CD workflows from project analysis",
|
||||
"main": "dist/index.js",
|
||||
"bin": {
|
||||
"ai-ci": "dist/cli.js"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc"
|
||||
},
|
||||
"keywords": [
|
||||
"ci",
|
||||
"cd",
|
||||
"github-actions",
|
||||
"ai",
|
||||
"cli"
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"commander": "^12.1.0",
|
||||
"glob": "^10.3.10",
|
||||
"openai": "^4.52.0",
|
||||
"ora": "^5.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.5.0",
|
||||
"@types/node": "^20.14.0"
|
||||
},
|
||||
"author": "LXGIC Studios",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/lxgicstudios/ai-ci"
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { Command } from "commander";
|
||||
import ora from "ora";
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import { scanProject, generateWorkflow } from "./index";
|
||||
|
||||
const program = new Command();
|
||||
|
||||
program
|
||||
.name("ai-ci")
|
||||
.description("Generates CI/CD workflows from project analysis")
|
||||
.version("1.0.0")
|
||||
.option("-p, --preview", "Preview without writing")
|
||||
.option("--provider <provider>", "CI provider", "github")
|
||||
.option("--deploy <target>", "Deploy target (vercel, netlify, aws, docker)")
|
||||
.option("-d, --dir <path>", "Project directory", ".")
|
||||
.option("-o, --output <path>", "Output path")
|
||||
.action(async (opts) => {
|
||||
const spinner = ora("Scanning project...").start();
|
||||
|
||||
try {
|
||||
const dir = path.resolve(opts.dir);
|
||||
const info = await scanProject(dir);
|
||||
|
||||
if (info.files.length === 0) {
|
||||
spinner.warn("No project files found. Are you in the right directory?");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
spinner.text = `Found ${info.files.length} config files. Generating workflow...`;
|
||||
|
||||
const workflow = await generateWorkflow(info, opts.provider, opts.deploy);
|
||||
|
||||
const defaultOutput = opts.provider === "github"
|
||||
? ".github/workflows/ci.yml"
|
||||
: "ci-workflow.yml";
|
||||
const outPath = path.resolve(opts.output || defaultOutput);
|
||||
|
||||
if (opts.preview) {
|
||||
spinner.stop();
|
||||
console.log(`\n--- Generated ${opts.provider} workflow ---\n`);
|
||||
console.log(workflow);
|
||||
console.log("\n-----------------------------------------\n");
|
||||
} else {
|
||||
const outDir = path.dirname(outPath);
|
||||
if (!fs.existsSync(outDir)) {
|
||||
fs.mkdirSync(outDir, { recursive: true });
|
||||
}
|
||||
fs.writeFileSync(outPath, workflow + "\n");
|
||||
spinner.succeed(`Workflow written to ${outPath}`);
|
||||
}
|
||||
} catch (err: any) {
|
||||
spinner.fail(err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
program.parse();
|
||||
@@ -1,65 +0,0 @@
|
||||
import OpenAI from "openai";
|
||||
import { glob } from "glob";
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
|
||||
const CONFIG_FILES = [
|
||||
"package.json", "tsconfig.json", "next.config.js", "next.config.mjs",
|
||||
"vite.config.ts", "nuxt.config.ts", "Cargo.toml", "go.mod",
|
||||
"pyproject.toml", "requirements.txt", "Gemfile", "build.gradle", "pom.xml",
|
||||
"jest.config.js", "jest.config.ts", "vitest.config.ts", ".eslintrc.js",
|
||||
".eslintrc.json", "prettier.config.js", "Makefile",
|
||||
"docker-compose.yml", "Dockerfile", "vercel.json", "netlify.toml",
|
||||
"fly.toml", "railway.json",
|
||||
];
|
||||
|
||||
export async function scanProject(dir: string): Promise<{ files: string[]; contents: Record<string, string> }> {
|
||||
const found: string[] = [];
|
||||
const contents: Record<string, string> = {};
|
||||
|
||||
for (const f of CONFIG_FILES) {
|
||||
const full = path.join(dir, f);
|
||||
if (fs.existsSync(full)) {
|
||||
found.push(f);
|
||||
const stat = fs.statSync(full);
|
||||
if (stat.size < 5000) {
|
||||
contents[f] = fs.readFileSync(full, "utf-8");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { files: found, contents };
|
||||
}
|
||||
|
||||
export async function generateWorkflow(
|
||||
projectInfo: { files: string[]; contents: Record<string, string> },
|
||||
provider: string,
|
||||
deployTarget?: string
|
||||
): Promise<string> {
|
||||
if (!process.env.OPENAI_API_KEY) {
|
||||
throw new Error("Missing OPENAI_API_KEY environment variable. Set it with: export OPENAI_API_KEY=sk-...");
|
||||
}
|
||||
|
||||
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
|
||||
|
||||
const deployInstruction = deployTarget
|
||||
? `Include a deployment step for ${deployTarget}. Use the standard ${deployTarget} GitHub Action or deployment method.`
|
||||
: "Don't include deployment steps, just CI (lint, test, build).";
|
||||
|
||||
const response = await openai.chat.completions.create({
|
||||
model: "gpt-4o-mini",
|
||||
messages: [
|
||||
{
|
||||
role: "system",
|
||||
content: `You are a CI/CD expert. Generate a ${provider === "github" ? "GitHub Actions" : provider} workflow YAML file. Output ONLY the YAML contents. No markdown code fences. Include proper caching, matrix testing if appropriate, and best practices. ${deployInstruction}`
|
||||
},
|
||||
{
|
||||
role: "user",
|
||||
content: `Project files: ${projectInfo.files.join(", ")}\n\nKey file contents:\n${Object.entries(projectInfo.contents).map(([k, v]) => `--- ${k} ---\n${v}`).join("\n\n")}`
|
||||
}
|
||||
],
|
||||
temperature: 0.3,
|
||||
});
|
||||
|
||||
return response.choices[0]?.message?.content?.trim() || "";
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "commonjs",
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"esModuleInterop": true,
|
||||
"strict": true,
|
||||
"resolveJsonModule": true,
|
||||
"declaration": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
Reference in New Issue
Block a user