diff --git a/.github/workflows/update-template-workflows.yml b/.github/workflows/update-template-workflows.yml index b96b6264..242b47d9 100644 --- a/.github/workflows/update-template-workflows.yml +++ b/.github/workflows/update-template-workflows.yml @@ -5,7 +5,7 @@ on: branches: - main paths: - - "templates/deploy.yaml" + - "templates/defang.yaml" workflow_dispatch: jobs: diff --git a/CLAUDE.md b/CLAUDE.md index 2e7275cb..cd7fb0b2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -25,9 +25,9 @@ samples/ <- Root ### Key Directories - **`samples/`** -- Every sample lives in its own kebab-case subdirectory here. Never place samples at the repo root. -- **`starter-sample/`** -- The scaffold copied by `. ./scripts/new-sample`. Contains `compose.yaml`, `compose.dev.yaml`, `README.md`, `.devcontainer/`, and `.github/workflows/deploy.yaml` with `#REMOVE_ME_AFTER_EDITING` markers. +- **`starter-sample/`** -- The scaffold copied by `. ./scripts/new-sample`. Contains `compose.yaml`, `compose.dev.yaml`, `README.md`, `.devcontainer/`, and `.github/workflows/defang.yaml` with `#REMOVE_ME_AFTER_EDITING` markers. - **`scripts/`** -- Automation scripts (Node.js). Run `npm ci` in this directory before using. -- **`templates/deploy.yaml`** -- The canonical deploy workflow. Each sample gets a copy managed by `template-manager.js` (do NOT manually create or edit `samples/*/.github/workflows/deploy.yaml`). +- **`templates/defang.yaml`** -- The canonical deploy workflow. Each sample gets a copy managed by `template-manager.js` (do NOT manually create or edit `samples/*/.github/workflows/defang.yaml`). - **`tools/testing/`** -- Go load test tool used by CI to deploy changed samples to staging and verify they come up healthy. --- @@ -138,9 +138,9 @@ For local development with hot-reload and local dependencies (like a local Mongo Devcontainer config for GitHub Codespaces / VS Code. The starter includes the Defang CLI feature, Docker-in-Docker, and AWS CLI. -### 6. `.github/workflows/deploy.yaml` (auto-generated) +### 6. `.github/workflows/defang.yaml` (auto-generated) -Do NOT create this manually. It is generated from `templates/deploy.yaml` by `template-manager.js` during CI. Pulumi samples are an exception and may have custom workflows. +Do NOT create this manually. It is generated from `templates/defang.yaml` by `template-manager.js` during CI. Pulumi samples are an exception and may have custom workflows. --- @@ -221,7 +221,7 @@ The test tool automatically strips the `TEST_` prefix and passes the values as D - No `.env` files with real secrets - No `node_modules/`, `__pycache__/`, build artifacts - No `.defang/` directory (already in `.gitignore`) -- No manually created `.github/workflows/deploy.yaml` (auto-generated from template) +- No manually created `.github/workflows/defang.yaml` (auto-generated from template) --- @@ -296,7 +296,7 @@ When submitting a new or modified sample: - [ ] `compose.yaml` passes `defang compose config` validation - [ ] README has all four metadata fields (`Title`, `Short Description`, `Tags`, `Languages`) - [ ] No `#REMOVE_ME_AFTER_EDITING` markers remain -- [ ] No `.github/workflows/deploy.yaml` manually added (auto-generated) +- [ ] No `.github/workflows/defang.yaml` manually added (auto-generated) - [ ] Sample builds and runs locally with `docker compose up --build` - [ ] Config values added to `deploy-changed-samples.yml` if secrets are needed - [ ] `node scripts/generate-samples-list.js` run if README metadata changed diff --git a/scripts/check-sample-files.sh b/scripts/check-sample-files.sh index 246908bd..8fda82d5 100755 --- a/scripts/check-sample-files.sh +++ b/scripts/check-sample-files.sh @@ -32,9 +32,9 @@ for dir in ./samples/*/; do fi fi - # Check that we NOT have a .github/workflows/deploy.yaml file; it's generated from templates/deploy.yaml - if [[ -f "${dir}.github/workflows/deploy.yaml" && "$pulumi" == "false" ]]; then - echo " - [ ] remove .github/workflows/deploy.yaml to ${dir} (generated file)" + # Check that we NOT have a .github/workflows/defang.yaml file; it's generated from templates/defang.yaml + if [[ -f "${dir}.github/workflows/defang.yaml" && "$pulumi" == "false" ]]; then + echo " - [ ] remove .github/workflows/defang.yaml from ${dir} (generated file)" fi if [[ ! -f "${dir}README.md" ]]; then diff --git a/scripts/template-manager.js b/scripts/template-manager.js index 2c0bdbd8..bc5f2abf 100644 --- a/scripts/template-manager.js +++ b/scripts/template-manager.js @@ -134,7 +134,7 @@ module.exports = async ({ github, context, core }) => { const response = await github.rest.repos.getContent({ owner: templateOrg, repo: templateRepoName, - path: '.github/workflows/deploy.yaml' + path: '.github/workflows/defang.yaml' }); currentWorkflow = Buffer.from(response.data.content, 'base64').toString(); } catch (err) { @@ -234,7 +234,7 @@ module.exports = async ({ github, context, core }) => { console.log(`@@ Generating workflow from compose.yaml`); const workflowContent = updateWorkflowFromCompose(); const workflowDir = '.github/workflows'; - const workflowPath = `${workflowDir}/deploy.yaml`; + const workflowPath = `${workflowDir}/defang.yaml`; // Ensure directory exists if (!fs.existsSync(workflowDir)) { diff --git a/scripts/update-template-workflows.js b/scripts/update-template-workflows.js index 2ca76b75..0796dd78 100644 --- a/scripts/update-template-workflows.js +++ b/scripts/update-template-workflows.js @@ -85,44 +85,64 @@ module.exports = async ({ github, context, core }) => { // Generate workflow from template + secrets const updatedContent = generateWorkflow(TEMPLATE, secrets); - // Get current workflow file - let currentFile; - try { - const response = await github.rest.repos.getContent({ - owner: templateOrg, - repo: repo.name, - path: '.github/workflows/deploy.yaml' - }); - currentFile = response.data; - } catch (err) { - if (err.status === 404) { - console.log(`${repo.name}: no workflow file found, skipping`); - skipped++; - continue; + const getFile = async (path) => { + try { + const response = await github.rest.repos.getContent({ + owner: templateOrg, + repo: repo.name, + path + }); + return response.data; + } catch (err) { + if (err.status === 404) return null; + throw err; } - throw err; + }; + + const currentFile = await getFile('.github/workflows/defang.yaml'); + const legacyFile = await getFile('.github/workflows/deploy.yaml'); + + if (!currentFile && !legacyFile) { + console.log(`${repo.name}: no workflow file found, skipping`); + skipped++; + continue; } - const currentContent = Buffer.from(currentFile.content, 'base64').toString(); + const currentContent = currentFile + ? Buffer.from(currentFile.content, 'base64').toString() + : null; - // Only update if changed - if (currentContent === updatedContent) { + const needsContentUpdate = currentContent !== updatedContent; + const needsLegacyDelete = !!legacyFile; + + if (!needsContentUpdate && !needsLegacyDelete) { console.log(`${repo.name}: already up to date`); skipped++; continue; } - // Update file - await github.rest.repos.createOrUpdateFileContents({ - owner: templateOrg, - repo: repo.name, - path: '.github/workflows/deploy.yaml', - message: 'Update workflow from canonical template', - content: Buffer.from(updatedContent).toString('base64'), - sha: currentFile.sha - }); - - console.log(`${repo.name}: updated`); + if (needsContentUpdate) { + await github.rest.repos.createOrUpdateFileContents({ + owner: templateOrg, + repo: repo.name, + path: '.github/workflows/defang.yaml', + message: 'Update workflow from canonical template', + content: Buffer.from(updatedContent).toString('base64'), + ...(currentFile ? { sha: currentFile.sha } : {}) + }); + } + + if (needsLegacyDelete) { + await github.rest.repos.deleteFile({ + owner: templateOrg, + repo: repo.name, + path: '.github/workflows/deploy.yaml', + message: 'Remove legacy deploy.yaml (renamed to defang.yaml)', + sha: legacyFile.sha + }); + } + + console.log(`${repo.name}: updated${needsLegacyDelete ? ' (removed legacy deploy.yaml)' : ''}`); updated++; } catch (err) { console.error(`${repo.name}: failed - ${err.message}`); diff --git a/scripts/workflow-utils.js b/scripts/workflow-utils.js index 730efe9f..6579343c 100644 --- a/scripts/workflow-utils.js +++ b/scripts/workflow-utils.js @@ -149,7 +149,7 @@ function generateWorkflow(template, secrets) { */ function loadWorkflowTemplate() { return fs.readFileSync( - path.join(__dirname, '..', 'templates', 'deploy.yaml'), + path.join(__dirname, '..', 'templates', 'defang.yaml'), 'utf8' ); } diff --git a/starter-sample/.github/workflows/deploy.yaml b/starter-sample/.github/workflows/defang.yaml similarity index 100% rename from starter-sample/.github/workflows/deploy.yaml rename to starter-sample/.github/workflows/defang.yaml diff --git a/templates/deploy.yaml b/templates/defang.yaml similarity index 99% rename from templates/deploy.yaml rename to templates/defang.yaml index b23c9c6d..f1a13234 100644 --- a/templates/deploy.yaml +++ b/templates/defang.yaml @@ -1,4 +1,4 @@ -name: Deploy +name: Defang on: push: