Skip to content

Commit

Permalink
Merge branch 'main' of github.com:tonik/stapler
Browse files Browse the repository at this point in the history
  • Loading branch information
maneike committed Oct 29, 2024
2 parents 4e70722 + f490803 commit 16e4d39
Show file tree
Hide file tree
Showing 16 changed files with 579 additions and 78 deletions.
8 changes: 8 additions & 0 deletions .changeset/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Changesets

Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
with multi-package repos, or single-package repos to help you version and publish your code. You can
find the full documentation for it [in our repository](https://github.com/changesets/changesets)

We have a quick list of common questions to get you started engaging with this project in
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
11 changes: 11 additions & 0 deletions .changeset/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"$schema": "https://unpkg.com/@changesets/[email protected]/schema.json",
"changelog": ["@changesets/cli/changelog", { "repo": "tonik/stapler" }],
"commit": false,
"fixed": [],
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": []
}
9 changes: 9 additions & 0 deletions .changeset/pre.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"mode": "pre",
"tag": "alpha",
"initialVersions": {
"@create-stapler-app/cli": "0.1.0",
"@create-stapler-app/core": "0.1.0"
},
"changesets": []
}
38 changes: 38 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Release

on:
push:
branches:
- main # or your default branch

concurrency: ${{ github.workflow }}-${{ github.ref }}

jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v3

- name: Setup Node.js 20.x
uses: actions/setup-node@v3
with:
node-version: 20.x

- name: Setup pnpm
uses: pnpm/[email protected]
with:
version: 9.6.0

- name: Install Dependencies
run: pnpm install

- name: Create Release Pull Request or Publish to npm
id: changesets
uses: changesets/action@v1
with:
publish: pnpm release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

**Stapler** is a CLI tool that scaffolds an entire fullstack app using a monorepo structure. It integrates **Next.js**, **Supabase**, **Payload CMS**, **Vercel**, and more, leveraging **Turbo** and **pnpm** to optimize your development workflow.

## Requirements
- node.js
- npx

## Features

- **Fullstack scaffolding**: Quickly set up a monorepo with Next.js, Supabase, Payload CMS, and Vercel.
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{
"name": "stapler",
"description": "Stapler: an amazing CLI tool that scaffolds an entire fullstack app for you",
"version": "0.1.0",
"private": true,
"scripts": {
"build": "turbo build",
Expand All @@ -8,6 +10,7 @@
"format": "prettier --write \"**/*.{ts,tsx,md}\""
},
"devDependencies": {
"@changesets/cli": "^2.27.9",
"prettier": "^3.2.5",
"turbo": "^2.1.1",
"typescript": "^5.4.5"
Expand All @@ -16,8 +19,6 @@
"engines": {
"node": ">=18"
},
"description": "This is an official starter Turborepo.",
"version": "1.0.0",
"main": "index.js",
"dependencies": {
"eslint": "^8.57.0",
Expand Down
6 changes: 5 additions & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
{
"name": "@create-stapler-app/cli",
"name": "@tonik/create-stapler-app",
"version": "0.1.0",
"main": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"bin": {
"create-stapler-app": "./dist/index.mjs"
},
"publishConfig": {
"access": "public",
"tag": "alpha"
},
"scripts": {
"build": "tsup index.ts --out-dir dist --format esm --dts",
"dev": "tsc -w"
Expand Down
1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "0.1.0",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"private": true,
"scripts": {
"build": "tsc --emitDeclarationOnly && tsup index.ts --out-dir dist --format cjs",
"dev": "tsc -w"
Expand Down
8 changes: 5 additions & 3 deletions packages/core/utils/supabase/connectProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const instructions = [
export const connectSupabaseProject = async (projectName: string, currentDir: string) => {
try {
console.log('๐Ÿ–‡๏ธ Getting information about newly created Supabase project...');
const { stdout: projectsList } = await execAsync('supabase projects list');
const { stdout: projectsList } = await execAsync('npx supabase projects list');
const projects = parseProjectsList(projectsList);
const newProject = projects.find((project) => project.name === projectName);

Expand All @@ -31,7 +31,9 @@ export const connectSupabaseProject = async (projectName: string, currentDir: st
}

console.log('๐Ÿ–‡๏ธ Getting Supabase project keys...');
const { stdout: projectAPIKeys } = await execAsync(`supabase projects api-keys --project-ref ${newProject.refId}`);
const { stdout: projectAPIKeys } = await execAsync(
`npx supabase projects api-keys --project-ref ${newProject.refId}`,
);

const { anonKey, serviceRoleKey } = getSupabaseKeys(projectAPIKeys);

Expand All @@ -52,7 +54,7 @@ export const connectSupabaseProject = async (projectName: string, currentDir: st
});

console.log('๐Ÿ–‡๏ธ Linking Supabase project...');
execSync(`supabase link --project-ref ${newProject.refId}`, { stdio: 'inherit' });
execSync(`npx supabase link --project-ref ${newProject.refId}`, { stdio: 'inherit' });

for (const instruction of instructions) {
console.log(instruction);
Expand Down
2 changes: 1 addition & 1 deletion packages/core/utils/supabase/createProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { execSync } from 'child_process';
export const createSupabaseProject = async (name: string) => {
console.log('๐Ÿ–‡๏ธ Creating Supabase project...');

execSync(`supabase projects create ${name}`, {
execSync(`npx supabase projects create ${name}`, {
stdio: 'inherit',
});
};
38 changes: 3 additions & 35 deletions packages/core/utils/supabase/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,16 @@ import path from 'path';
import { supabaseFiles } from '../../templates/supabase/installConfig';
import { templateGenerator } from '../generator/generator';

const checkAndInstallSupabaseCLI = (): void => {
console.log('๐Ÿ–‡๏ธ Checking Supabase CLI installation...');

try {
execSync('supabase --version', { stdio: 'ignore' });
} catch (error) {
console.log('๐Ÿ–‡๏ธ Installing Supabase CLI...');
try {
// For macOS/Linux using Homebrew
if (process.platform === 'darwin' || process.platform === 'linux') {
execSync('brew install supabase/tap/supabase', { stdio: 'inherit' });
}
// For Windows using npm
else if (process.platform === 'win32') {
execSync('npm install -g supabase', { stdio: 'inherit' });
} else {
throw new Error('Unsupported operating system');
}
} catch (installError) {
console.error('\n๐Ÿ–‡๏ธ Failed to install Supabase CLI automatically. Please install it manually:');
console.log('\n๐Ÿ–‡๏ธ MacOS/Linux:');
console.log('๐Ÿ–‡๏ธ brew install supabase/tap/supabase');
console.log('\n๐Ÿ–‡๏ธ Windows:');
console.log('๐Ÿ–‡๏ธ npm install -g supabase');
console.log('\n๐Ÿ–‡๏ธ For other installation methods, visit:');
console.log('๐Ÿ–‡๏ธ https://supabase.com/docs/guides/local-development/cli/getting-started \n');
process.exit(1);
}
}
};

const supabaseLogin = () => {
console.log('๐Ÿ–‡๏ธ Logging into Supabase...');

try {
execSync('supabase projects list', { stdio: 'ignore' });
execSync('npx supabase projects list', { stdio: 'ignore' });
console.log('๐Ÿ–‡๏ธ Already logged into Supabase. Skipping login.');
return;
} catch (error) {
try {
execSync('supabase login', { stdio: 'inherit' });
execSync('npx supabase login', { stdio: 'inherit' });
} catch {
console.error('\n๐Ÿ–‡๏ธ Failed to log in to Supabase.');
console.log('\n๐Ÿ–‡๏ธ Please log in manually with "supabase login" and re-run "create-stapler-app".');
Expand All @@ -56,7 +25,7 @@ const supabaseLogin = () => {
const initializeSupabaseProject = (): void => {
console.log('๐Ÿ–‡๏ธ Initialize Supabase project...');
try {
execSync(`supabase init`, { stdio: ['pipe'], encoding: 'utf-8' });
execSync(`npx supabase init`, { stdio: ['pipe'], encoding: 'utf-8' });
} catch (error: any) {
const errorMessage = error.stderr;

Expand All @@ -76,7 +45,6 @@ const initializeSupabaseProject = (): void => {
export const installSupabase = async (destinationDirectory: string) => {
console.log('๐Ÿ–‡๏ธ Installing supabase-js...');
try {
checkAndInstallSupabaseCLI();
supabaseLogin();
initializeSupabaseProject();
} catch (error) {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/utils/vercel/connectWithGH.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const connectWithGH = async () => {

for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
try {
execSync('vercel git connect', {
execSync('npx vercel git connect', {
stdio: ['pipe'],
encoding: 'utf-8',
});
Expand Down
10 changes: 5 additions & 5 deletions packages/core/utils/vercel/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ export const deployVercelProject = async () => {

await fs.writeFile('vercel.json', JSON.stringify(vercelConfig, null, 2));

console.log('๐Ÿ–‡๏ธ Creating preview deployment...');
const previewUrl = getDeploymentUrl(false);

console.log('๐Ÿ–‡๏ธ Creating production deployment...');
const productionUrl = getDeploymentUrl(true);

console.log(`๐Ÿ–‡๏ธ You can access your preview deployment at: \x1b[36m${previewUrl}\x1b[0m$`);
console.log('๐Ÿ–‡๏ธ Creating preview deployment...');
const previewUrl = getDeploymentUrl(false);

console.log(`๐Ÿ–‡๏ธ You can access your preview deployment at: \x1b[36m${previewUrl}\x1b[0m`);

console.log(`๐Ÿ–‡๏ธ You can access your production deployment at: \x1b[36m${productionUrl}\x1b[0m$`);
console.log(`๐Ÿ–‡๏ธ You can access your production deployment at: \x1b[36m${productionUrl}\x1b[0m`);
};
34 changes: 5 additions & 29 deletions packages/core/utils/vercel/setupAndCreate.ts
Original file line number Diff line number Diff line change
@@ -1,53 +1,29 @@
import { execSync } from 'child_process';

const vercelVersion = (): boolean => {
try {
execSync('vercel --version', { encoding: 'utf8' });
return true;
} catch {
return false;
}
};

const getUserName = (): string | null => {
try {
const user = execSync('vercel whoami', { stdio: 'pipe', encoding: 'utf-8' });
console.log('test', user);
const user = execSync('npx vercel whoami', { stdio: 'pipe', encoding: 'utf-8' });
return user;
} catch {
return null;
}
};

export const setupAndCreateVercelProject = async () => {
console.log('๐Ÿ–‡๏ธ Checking if Vercel CLI is installed...');

const isVercelInstalled = vercelVersion();

if (!isVercelInstalled) {
console.log('๐Ÿ–‡๏ธ Installing Vercel CLI...');
try {
execSync('npm install -g vercel');
} catch {
console.error('๐Ÿ–‡๏ธ Failed to install Vercel CLI...');
process.exit(1);
}
}

const vercelUserName = getUserName();

if (!vercelUserName) {
console.log('๐Ÿ–‡๏ธ Logging in to Vercel...');
try {
execSync('vercel login', { stdio: 'inherit' });
execSync('npx vercel login', { stdio: 'inherit' });
} catch (error) {
console.log('\n๐Ÿ–‡๏ธ Oops! Something went wrong while logging in to Vercel...');
console.log('๐Ÿ–‡๏ธ You might already be logged in with this email in another project.');
console.log(
'๐Ÿ–‡๏ธ In this case, select "Continue with Email" and enter the email you\'re already logged in with.\n',
);
try {
execSync('vercel login', { stdio: 'inherit' });
execSync('npx vercel login', { stdio: 'inherit' });
} catch {
console.log('\n๐Ÿ–‡๏ธ Please check the error above and try again.');
console.log('๐Ÿ–‡๏ธ After successfully logging in with "vercel login", please run create-stapler-app again.\n');
Expand All @@ -59,8 +35,8 @@ export const setupAndCreateVercelProject = async () => {
}

console.log('๐Ÿ–‡๏ธ Initializing Vercel project...');
execSync('vercel init');
execSync('npx vercel init');

console.log('๐Ÿ–‡๏ธ Linking Vercel project...');
execSync('vercel link', { stdio: 'inherit' });
execSync('npx vercel link', { stdio: 'inherit' });
};
5 changes: 4 additions & 1 deletion packages/core/utils/vercel/utils/getDeploymentUrl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ export const getDeploymentUrl = (production: boolean = false): string => {
const command = production ? 'vercel --prod' : 'vercel';

try {
const output = execSync(command, { encoding: 'utf8' });
const output = execSync(command, {
stdio: ['inherit', 'pipe', 'inherit'],
encoding: 'utf8',
});

if (output) {
return output;
Expand Down
Loading

0 comments on commit 16e4d39

Please sign in to comment.