From b8e4fbc0b200dfb49e5b40ae71e446b408741e0f Mon Sep 17 00:00:00 2001 From: Aymane Dara Hlamnach Date: Tue, 30 Dec 2025 15:30:45 +0100 Subject: [PATCH 1/3] feat: origin env vars --- package.json | 8 +++++++- packages/app/lib/cli/commands/app/dev.ts | 2 ++ packages/create-app/lib/services/init.ts | 14 ++++++++++---- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index fb58202..1f3be3e 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,12 @@ "ejs@<3.1.10": ">=3.1.10", "tar@<6.2.1": ">=6.2.1", "ws@>=8.0.0 <8.17.1": ">=8.17.1" - } + }, + "onlyBuiltDependencies": [ + "esbuild", + "mmap-io", + "shmmap", + "yarn" + ] } } diff --git a/packages/app/lib/cli/commands/app/dev.ts b/packages/app/lib/cli/commands/app/dev.ts index f56c624..04e4eba 100644 --- a/packages/app/lib/cli/commands/app/dev.ts +++ b/packages/app/lib/cli/commands/app/dev.ts @@ -199,6 +199,8 @@ class Dev extends AppCommand { YOUCAN_API_KEY: this.app.remote_config.client_id, YOUCAN_API_SECRET: this.app.remote_config.client_secret, YOUCAN_API_SCOPES: this.app.remote_config.scopes.join(','), + YOUCAN_API_URL: `https://${Env.apiHostname()}`, + YOUCAN_SELLER_AREA_URL: `https://${Env.sellerAreaHostname()}`, APP_URL: this.app.network_config.app_url, PORT: this.app.network_config.app_port.toString(), }; diff --git a/packages/create-app/lib/services/init.ts b/packages/create-app/lib/services/init.ts index 4c2d5d0..8ad4bd9 100644 --- a/packages/create-app/lib/services/init.ts +++ b/packages/create-app/lib/services/init.ts @@ -45,10 +45,16 @@ async function initService(command: Cli.Command, options: InitServiceOptions) { { title: 'Configuring app...', task: async () => { - await Filesystem.writeJsonFile( - Path.join(templateDownloadDirectory, 'youcan.app.json'), - { name: slug }, - ); + const configPath = Path.join(templateDownloadDirectory, 'youcan.app.json'); + const configExists = await Filesystem.exists(configPath); + + if (configExists) { + const existingConfig = await Filesystem.readJsonFile(configPath); + await Filesystem.writeJsonFile(configPath, { ...existingConfig, name: slug }); + } + else { + await Filesystem.writeJsonFile(configPath, { name: slug }); + } }, }, { From 3662c9ff1ca3624c3cba2151d6575475cefb468c Mon Sep 17 00:00:00 2001 From: Aymane Dara Hlamnach Date: Tue, 30 Dec 2025 15:38:29 +0100 Subject: [PATCH 2/3] =?UTF-8?q?=E3=80=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/app/lib/cli/commands/app/dev.ts | 7 +-- packages/app/lib/cli/commands/app/env/pull.ts | 49 +++++++++++++++++++ packages/app/lib/cli/commands/app/env/show.ts | 13 +++-- .../lib/cli/services/environment-variables.ts | 16 ++++++ 4 files changed, 73 insertions(+), 12 deletions(-) create mode 100644 packages/app/lib/cli/commands/app/env/pull.ts create mode 100644 packages/app/lib/cli/services/environment-variables.ts diff --git a/packages/app/lib/cli/commands/app/dev.ts b/packages/app/lib/cli/commands/app/dev.ts index 04e4eba..f1f9ef7 100644 --- a/packages/app/lib/cli/commands/app/dev.ts +++ b/packages/app/lib/cli/commands/app/dev.ts @@ -1,6 +1,7 @@ import type { Cli, Worker } from '@youcan/cli-kit'; import process from 'node:process'; import { bootAppWorker, bootExtensionWorker, bootTunnelWorker, bootWebWorker } from '@/cli/services/dev/workers'; +import { getAppEnvironmentVariables } from '@/cli/services/environment-variables'; import { APP_CONFIG_FILENAME } from '@/constants'; import { AppCommand } from '@/util/app-command'; import { load } from '@/util/app-loader'; @@ -196,11 +197,7 @@ class Dev extends AppCommand { } return { - YOUCAN_API_KEY: this.app.remote_config.client_id, - YOUCAN_API_SECRET: this.app.remote_config.client_secret, - YOUCAN_API_SCOPES: this.app.remote_config.scopes.join(','), - YOUCAN_API_URL: `https://${Env.apiHostname()}`, - YOUCAN_SELLER_AREA_URL: `https://${Env.sellerAreaHostname()}`, + ...getAppEnvironmentVariables(this.app), APP_URL: this.app.network_config.app_url, PORT: this.app.network_config.app_port.toString(), }; diff --git a/packages/app/lib/cli/commands/app/env/pull.ts b/packages/app/lib/cli/commands/app/env/pull.ts new file mode 100644 index 0000000..ccfa7f4 --- /dev/null +++ b/packages/app/lib/cli/commands/app/env/pull.ts @@ -0,0 +1,49 @@ +import { getAppEnvironmentVariables } from '@/cli/services/environment-variables'; +import { AppCommand } from '@/util/app-command'; +import { load } from '@/util/app-loader'; +import { Flags } from '@oclif/core'; +import { Color, Filesystem, Path, Session, Tasks, UI } from '@youcan/cli-kit'; + +class EnvPull extends AppCommand { + static description = 'Create or update a .env file with app environment variables'; + + static flags = { + 'env-file': Flags.string({ + description: 'Path to the .env file to create or update', + default: '.env', + }), + }; + + async run(): Promise { + const { flags } = await this.parse(EnvPull); + const envFilePath = Path.resolve(flags['env-file']); + + this.app = await load(); + this.session = await Session.authenticate(this); + + await Tasks.run({}, [ + { + title: 'Syncing app configuration..', + task: async () => { await this.syncAppConfig(); }, + }, + ]); + + await this.writeEnvFile(envFilePath); + } + + private async writeEnvFile(filePath: string) { + const envVars = getAppEnvironmentVariables(this.app); + + const envContent = Object.entries(envVars) + .map(([key, value]) => `${key}=${value}`) + .join('\n'); + + await Filesystem.writeFile(filePath, `${envContent}\n`); + + this.log(); + this.log(`${Color.green('[OK]')} Environment variables written to ${Color.cyan(filePath)}`); + this.log(); + } +} + +export default EnvPull; diff --git a/packages/app/lib/cli/commands/app/env/show.ts b/packages/app/lib/cli/commands/app/env/show.ts index b55f9a2..f32f221 100644 --- a/packages/app/lib/cli/commands/app/env/show.ts +++ b/packages/app/lib/cli/commands/app/env/show.ts @@ -1,6 +1,7 @@ +import { getAppEnvironmentVariables } from '@/cli/services/environment-variables'; import { AppCommand } from '@/util/app-command'; import { load } from '@/util/app-loader'; -import { Color, Session, Tasks } from '@youcan/cli-kit'; +import { Color, Env, Session, Tasks } from '@youcan/cli-kit'; class EnvShow extends AppCommand { static description = 'Display app environment variables'; @@ -20,14 +21,12 @@ class EnvShow extends AppCommand { } private async printEnvironmentVariables() { - if (!this.app.remote_config) { - throw new Error('remote app config not loaded'); - } + const envVars = getAppEnvironmentVariables(this.app); this.log(); - this.log(`${Color.yellow('YOUCAN_API_KEY')}=%s`, this.app.remote_config.client_id); - this.log(`${Color.yellow('YOUCAN_API_SECRET')}=%s`, this.app.remote_config.client_secret); - this.log(`${Color.yellow('YOUCAN_API_SCOPES')}=%s`, this.app.remote_config.scopes.join(',')); + for (const [key, value] of Object.entries(envVars)) { + this.log(`${Color.yellow(key)}=${value}`); + } } } diff --git a/packages/app/lib/cli/services/environment-variables.ts b/packages/app/lib/cli/services/environment-variables.ts new file mode 100644 index 0000000..3d99f15 --- /dev/null +++ b/packages/app/lib/cli/services/environment-variables.ts @@ -0,0 +1,16 @@ +import type { App } from '@/types'; +import { Env } from '@youcan/cli-kit'; + +export function getAppEnvironmentVariables(app: App): Record { + if (!app.remote_config) { + throw new Error('remote app config not loaded'); + } + + return { + YOUCAN_API_KEY: app.remote_config.client_id, + YOUCAN_API_SECRET: app.remote_config.client_secret, + YOUCAN_API_SCOPES: app.remote_config.scopes.join(','), + YOUCAN_API_URL: `https://${Env.apiHostname()}`, + YOUCAN_SELLER_AREA_URL: `https://${Env.sellerAreaHostname()}`, + }; +} From 5954c74e60f53f095970b500845e64ebf438c6f8 Mon Sep 17 00:00:00 2001 From: Aymane Dara Hlamnach Date: Tue, 30 Dec 2025 15:46:11 +0100 Subject: [PATCH 3/3] =?UTF-8?q?=E3=80=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yaml | 37 ++++++++++++++++++++++++++++++++++ package.json | 3 ++- 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/release.yaml diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..17e700e --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,37 @@ +name: Release + +permissions: + contents: write + id-token: write + +on: + push: + tags: + - 'v*' + workflow_dispatch: + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - uses: pnpm/action-setup@v4 + + - uses: actions/setup-node@v6 + with: + node-version: 22 + registry-url: 'https://registry.npmjs.org' + + - run: pnpm install --frozen-lockfile + + - run: pnpm build + + - run: npx changelogithub + env: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + + - run: npm i -g npm@latest + - run: pnpm -r --dir packages --no-git-checks publish --access public --provenance diff --git a/package.json b/package.json index 1f3be3e..64443d1 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "lint": "eslint --fix packages/**/*.{ts,js,json}", "test": "pnpm -r test", "test:watch": "pnpm -r test:watch", - "release": "pnpm build && bumpp packages/*/package.json --commit \"release: v\" --push --tag && pnpm -r release" + "bump": "bumpp package.json packages/*/package.json --commit \"release: v\" --push --tag", + "release": "pnpm bump" }, "workspaces": { "packages": [