From 8f28f2986a5575863cb0fac5afdd9c3113f93fa9 Mon Sep 17 00:00:00 2001 From: Lionello Lunesu Date: Mon, 2 Feb 2026 21:02:17 -0800 Subject: [PATCH 1/5] chore: use a single deploy workflow template --- .github/workflows/publish-sample-template.yml | 6 +- .github/workflows/test-scripts.yml | 65 +++++ .../workflows/update-template-workflows.yml | 37 +++ .../.github/workflows/deploy.yaml | 25 -- .../.github/workflows/deploy.yaml | 25 -- .../.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 26 -- .../.github/workflows/deploy.yaml | 27 -- .../.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 25 -- samples/django/.github/workflows/deploy.yaml | 21 -- samples/elysia/.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 26 -- .../.github/workflows/deploy.yaml | 21 -- samples/fastapi/.github/workflows/deploy.yaml | 21 -- .../feathersjs/.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- samples/flask/.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- .../golang-http/.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- .../golang-s3/.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- samples/hasura/.github/workflows/deploy.yaml | 21 -- .../html-css-js/.github/workflows/deploy.yaml | 21 -- samples/huginn/.github/workflows/deploy.yaml | 21 -- .../imgproxy/.github/workflows/deploy.yaml | 21 -- samples/javalin/.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 26 -- .../langchain/.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- .../managed-llm/.github/workflows/deploy.yaml | 25 -- .../.github/workflows/deploy.yaml | 28 -- samples/mcp/.github/workflows/deploy.yaml | 25 -- .../metabase/.github/workflows/deploy.yaml | 21 -- samples/n8n/.github/workflows/deploy.yaml | 28 -- .../nextjs-blog/.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 25 -- .../nextjs-cv/.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 26 -- .../.github/workflows/deploy.yaml | 21 -- samples/nextjs/.github/workflows/deploy.yaml | 21 -- samples/nocodb/.github/workflows/deploy.yaml | 30 --- .../.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- .../nodejs-form/.github/workflows/deploy.yaml | 21 -- .../nodejs-http/.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- .../nodejs-s3/.github/workflows/deploy.yaml | 21 -- samples/nounly/.github/workflows/deploy.yaml | 26 -- samples/ollama/.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 20 -- .../python-form/.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- .../python-s3/.github/workflows/deploy.yaml | 21 -- samples/rails/.github/workflows/deploy.yaml | 25 -- .../.github/workflows/deploy.yaml | 20 -- samples/react/.github/workflows/deploy.yaml | 20 -- .../redis-js/.github/workflows/deploy.yaml | 21 -- samples/rocket/.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- samples/sailsjs/.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- .../.github/workflows/deploy.yaml | 21 -- .../sveltekit/.github/workflows/deploy.yaml | 21 -- samples/vllm/.github/workflows/deploy.yaml | 21 -- samples/vuejs/.github/workflows/deploy.yaml | 21 -- scripts/package-lock.json | 19 +- scripts/package.json | 6 +- scripts/template-manager.js | 155 ++++++++++- scripts/update-template-workflows.js | 136 ++++++++++ scripts/workflow-utils.js | 163 ++++++++++++ scripts/workflow-utils.test.js | 250 ++++++++++++++++++ .../workflows => templates}/deploy.yaml | 6 - 88 files changed, 829 insertions(+), 1731 deletions(-) create mode 100644 .github/workflows/test-scripts.yml create mode 100644 .github/workflows/update-template-workflows.yml delete mode 100644 samples/agentic-autogen/.github/workflows/deploy.yaml delete mode 100644 samples/agentic-langgraph/.github/workflows/deploy.yaml delete mode 100644 samples/agentic-strands/.github/workflows/deploy.yaml delete mode 100644 samples/angular-express/.github/workflows/deploy.yaml delete mode 100644 samples/arduino-wifi/.github/workflows/deploy.yaml delete mode 100644 samples/bullmq-bullboard-redis/.github/workflows/deploy.yaml delete mode 100644 samples/csharp-dotnet/.github/workflows/deploy.yaml delete mode 100644 samples/django-celery/.github/workflows/deploy.yaml delete mode 100644 samples/django-postgres/.github/workflows/deploy.yaml delete mode 100644 samples/django-railpack/.github/workflows/deploy.yaml delete mode 100644 samples/django-redis-postgres/.github/workflows/deploy.yaml delete mode 100644 samples/django/.github/workflows/deploy.yaml delete mode 100644 samples/elysia/.github/workflows/deploy.yaml delete mode 100644 samples/fastapi-postgres-pubsub/.github/workflows/deploy.yaml delete mode 100644 samples/fastapi-postgres/.github/workflows/deploy.yaml delete mode 100644 samples/fastapi/.github/workflows/deploy.yaml delete mode 100644 samples/feathersjs/.github/workflows/deploy.yaml delete mode 100644 samples/flask-railpack/.github/workflows/deploy.yaml delete mode 100644 samples/flask/.github/workflows/deploy.yaml delete mode 100644 samples/golang-http-form/.github/workflows/deploy.yaml delete mode 100644 samples/golang-http/.github/workflows/deploy.yaml delete mode 100644 samples/golang-mongodb/.github/workflows/deploy.yaml delete mode 100644 samples/golang-openai/.github/workflows/deploy.yaml delete mode 100644 samples/golang-railpack/.github/workflows/deploy.yaml delete mode 100644 samples/golang-rest-api/.github/workflows/deploy.yaml delete mode 100644 samples/golang-s3/.github/workflows/deploy.yaml delete mode 100644 samples/golang-slackbot/.github/workflows/deploy.yaml delete mode 100644 samples/hasura/.github/workflows/deploy.yaml delete mode 100644 samples/html-css-js/.github/workflows/deploy.yaml delete mode 100644 samples/huginn/.github/workflows/deploy.yaml delete mode 100644 samples/imgproxy/.github/workflows/deploy.yaml delete mode 100644 samples/javalin/.github/workflows/deploy.yaml delete mode 100644 samples/jupyter-postgres/.github/workflows/deploy.yaml delete mode 100644 samples/langchain/.github/workflows/deploy.yaml delete mode 100644 samples/managed-llm-provider/.github/workflows/deploy.yaml delete mode 100644 samples/managed-llm/.github/workflows/deploy.yaml delete mode 100644 samples/mastra-nextjs/.github/workflows/deploy.yaml delete mode 100644 samples/mcp/.github/workflows/deploy.yaml delete mode 100644 samples/metabase/.github/workflows/deploy.yaml delete mode 100644 samples/n8n/.github/workflows/deploy.yaml delete mode 100644 samples/nextjs-blog/.github/workflows/deploy.yaml delete mode 100644 samples/nextjs-claude/.github/workflows/deploy.yaml delete mode 100644 samples/nextjs-cv/.github/workflows/deploy.yaml delete mode 100644 samples/nextjs-documentation/.github/workflows/deploy.yaml delete mode 100644 samples/nextjs-postgres/.github/workflows/deploy.yaml delete mode 100644 samples/nextjs-railpack/.github/workflows/deploy.yaml delete mode 100644 samples/nextjs/.github/workflows/deploy.yaml delete mode 100644 samples/nocodb/.github/workflows/deploy.yaml delete mode 100644 samples/nodejs-chatroom/.github/workflows/deploy.yaml delete mode 100644 samples/nodejs-express/.github/workflows/deploy.yaml delete mode 100644 samples/nodejs-form/.github/workflows/deploy.yaml delete mode 100644 samples/nodejs-http/.github/workflows/deploy.yaml delete mode 100644 samples/nodejs-openai/.github/workflows/deploy.yaml delete mode 100644 samples/nodejs-react-postgres/.github/workflows/deploy.yaml delete mode 100644 samples/nodejs-rest-api/.github/workflows/deploy.yaml delete mode 100644 samples/nodejs-s3/.github/workflows/deploy.yaml delete mode 100644 samples/nounly/.github/workflows/deploy.yaml delete mode 100644 samples/ollama/.github/workflows/deploy.yaml delete mode 100644 samples/phoenix-postgres/.github/workflows/deploy.yaml delete mode 100644 samples/platformatic/.github/workflows/deploy.yaml delete mode 100644 samples/python-form/.github/workflows/deploy.yaml delete mode 100644 samples/python-implicit-gpu/.github/workflows/deploy.yaml delete mode 100644 samples/python-minimal/.github/workflows/deploy.yaml delete mode 100644 samples/python-openai/.github/workflows/deploy.yaml delete mode 100644 samples/python-rest-api/.github/workflows/deploy.yaml delete mode 100644 samples/python-s3/.github/workflows/deploy.yaml delete mode 100644 samples/rails/.github/workflows/deploy.yaml delete mode 100644 samples/react-vite-railpack/.github/workflows/deploy.yaml delete mode 100644 samples/react/.github/workflows/deploy.yaml delete mode 100644 samples/redis-js/.github/workflows/deploy.yaml delete mode 100644 samples/rocket/.github/workflows/deploy.yaml delete mode 100644 samples/sailsjs-postgres/.github/workflows/deploy.yaml delete mode 100644 samples/sailsjs/.github/workflows/deploy.yaml delete mode 100644 samples/svelte-mysql/.github/workflows/deploy.yaml delete mode 100644 samples/sveltekit-mongodb/.github/workflows/deploy.yaml delete mode 100644 samples/sveltekit/.github/workflows/deploy.yaml delete mode 100644 samples/vllm/.github/workflows/deploy.yaml delete mode 100644 samples/vuejs/.github/workflows/deploy.yaml create mode 100644 scripts/update-template-workflows.js create mode 100644 scripts/workflow-utils.js create mode 100644 scripts/workflow-utils.test.js rename {samples/crewai/.github/workflows => templates}/deploy.yaml (73%) diff --git a/.github/workflows/publish-sample-template.yml b/.github/workflows/publish-sample-template.yml index c572ef2d..ec1c66a5 100644 --- a/.github/workflows/publish-sample-template.yml +++ b/.github/workflows/publish-sample-template.yml @@ -1,19 +1,19 @@ name: Publish Sample Template on: - push: + push: branches: - main jobs: publish_samples: runs-on: ubuntu-latest - permissions: + permissions: contents: write pull-requests: write steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: # Fetch two to see changes in current commit fetch-depth: 2 diff --git a/.github/workflows/test-scripts.yml b/.github/workflows/test-scripts.yml new file mode 100644 index 00000000..6293f6e9 --- /dev/null +++ b/.github/workflows/test-scripts.yml @@ -0,0 +1,65 @@ +name: Test Scripts + +on: + pull_request: + paths: + - "scripts/**" + - "templates/**" + - "samples/**/compose.yaml" + - "samples/**/compose.yml" + push: + branches: + - main + paths: + - "scripts/**" + - "templates/**" + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + + - name: Install dependencies + run: npm install + working-directory: scripts + + - name: Run tests + run: npm test + working-directory: scripts + + preview-workflows: + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 2 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + + - name: Install dependencies + run: npm install + working-directory: scripts + + - name: Get changed samples + run: ./scripts/check-modified-samples.sh > modified.txt + + - name: Preview workflows + uses: actions/github-script@v7 + env: + DRY_RUN: "true" + with: + script: | + const script = require('./scripts/template-manager.js') + await script({github, context, core}); diff --git a/.github/workflows/update-template-workflows.yml b/.github/workflows/update-template-workflows.yml new file mode 100644 index 00000000..90dee98d --- /dev/null +++ b/.github/workflows/update-template-workflows.yml @@ -0,0 +1,37 @@ +name: Update Template Workflows + +on: + push: + branches: + - main + paths: + - "templates/deploy.yaml" + workflow_dispatch: + +jobs: + update_workflows: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + + - name: Install dependencies + run: npm install + working-directory: scripts + + - name: Update Template Workflows + uses: actions/github-script@v7 + env: + PUSH_TOKEN: ${{ secrets.TEMPLATES_MANAGER_TOKEN }} + with: + github-token: ${{ secrets.TEMPLATES_MANAGER_TOKEN }} + script: | + const script = require('./scripts/update-template-workflows.js') + await script({github, context, core}); diff --git a/samples/agentic-autogen/.github/workflows/deploy.yaml b/samples/agentic-autogen/.github/workflows/deploy.yaml deleted file mode 100644 index c7c2ff00..00000000 --- a/samples/agentic-autogen/.github/workflows/deploy.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 - with: - config-env-vars: MISTRAL_API_KEY - env: - MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }} diff --git a/samples/agentic-langgraph/.github/workflows/deploy.yaml b/samples/agentic-langgraph/.github/workflows/deploy.yaml deleted file mode 100644 index 7c2860fe..00000000 --- a/samples/agentic-langgraph/.github/workflows/deploy.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 - with: - config-env-vars: TAVILY_API_KEY - env: - TAVILY_API_KEY: ${{ secrets.TAVILY_API_KEY }} diff --git a/samples/agentic-strands/.github/workflows/deploy.yaml b/samples/agentic-strands/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/agentic-strands/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/angular-express/.github/workflows/deploy.yaml b/samples/angular-express/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/angular-express/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/arduino-wifi/.github/workflows/deploy.yaml b/samples/arduino-wifi/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/arduino-wifi/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/bullmq-bullboard-redis/.github/workflows/deploy.yaml b/samples/bullmq-bullboard-redis/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/bullmq-bullboard-redis/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/csharp-dotnet/.github/workflows/deploy.yaml b/samples/csharp-dotnet/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/csharp-dotnet/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/django-celery/.github/workflows/deploy.yaml b/samples/django-celery/.github/workflows/deploy.yaml deleted file mode 100644 index c6ac88d9..00000000 --- a/samples/django-celery/.github/workflows/deploy.yaml +++ /dev/null @@ -1,26 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 - with: - config-env-vars: POSTGRES_PASSWORD SECRET_KEY - env: - POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }} - SECRET_KEY: ${{ secrets.SECRET_KEY }} diff --git a/samples/django-postgres/.github/workflows/deploy.yaml b/samples/django-postgres/.github/workflows/deploy.yaml deleted file mode 100644 index 3f22e5c1..00000000 --- a/samples/django-postgres/.github/workflows/deploy.yaml +++ /dev/null @@ -1,27 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 - with: - config-env-vars: POSTGRES_PASSWORD SECRET_KEY ALLOWED_HOSTS - env: - POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }} - SECRET_KEY: ${{ secrets.SECRET_KEY }} - ALLOWED_HOSTS: ${{ secrets.ALLOWED_HOSTS }} diff --git a/samples/django-railpack/.github/workflows/deploy.yaml b/samples/django-railpack/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/django-railpack/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/django-redis-postgres/.github/workflows/deploy.yaml b/samples/django-redis-postgres/.github/workflows/deploy.yaml deleted file mode 100644 index 2befba4a..00000000 --- a/samples/django-redis-postgres/.github/workflows/deploy.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 - with: - config-env-vars: SECRET_KEY POSTGRES_PASSWORD - env: - SECRET_KEY: ${{ secrets.SECRET_KEY }} - POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }} \ No newline at end of file diff --git a/samples/django/.github/workflows/deploy.yaml b/samples/django/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/django/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/elysia/.github/workflows/deploy.yaml b/samples/elysia/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/elysia/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/fastapi-postgres-pubsub/.github/workflows/deploy.yaml b/samples/fastapi-postgres-pubsub/.github/workflows/deploy.yaml deleted file mode 100644 index 68e718c4..00000000 --- a/samples/fastapi-postgres-pubsub/.github/workflows/deploy.yaml +++ /dev/null @@ -1,26 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 - with: - config-env-vars: POSTGRES_PASSWORD SSL_MODE - env: - POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }} - SSL_MODE: ${{ secrets.SSL_MODE }} diff --git a/samples/fastapi-postgres/.github/workflows/deploy.yaml b/samples/fastapi-postgres/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/fastapi-postgres/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/fastapi/.github/workflows/deploy.yaml b/samples/fastapi/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/fastapi/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/feathersjs/.github/workflows/deploy.yaml b/samples/feathersjs/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/feathersjs/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/flask-railpack/.github/workflows/deploy.yaml b/samples/flask-railpack/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/flask-railpack/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/flask/.github/workflows/deploy.yaml b/samples/flask/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/flask/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/golang-http-form/.github/workflows/deploy.yaml b/samples/golang-http-form/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/golang-http-form/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/golang-http/.github/workflows/deploy.yaml b/samples/golang-http/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/golang-http/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/golang-mongodb/.github/workflows/deploy.yaml b/samples/golang-mongodb/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/golang-mongodb/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/golang-openai/.github/workflows/deploy.yaml b/samples/golang-openai/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/golang-openai/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/golang-railpack/.github/workflows/deploy.yaml b/samples/golang-railpack/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/golang-railpack/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/golang-rest-api/.github/workflows/deploy.yaml b/samples/golang-rest-api/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/golang-rest-api/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/golang-s3/.github/workflows/deploy.yaml b/samples/golang-s3/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/golang-s3/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/golang-slackbot/.github/workflows/deploy.yaml b/samples/golang-slackbot/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/golang-slackbot/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/hasura/.github/workflows/deploy.yaml b/samples/hasura/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/hasura/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/html-css-js/.github/workflows/deploy.yaml b/samples/html-css-js/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/html-css-js/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/huginn/.github/workflows/deploy.yaml b/samples/huginn/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/huginn/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/imgproxy/.github/workflows/deploy.yaml b/samples/imgproxy/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/imgproxy/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/javalin/.github/workflows/deploy.yaml b/samples/javalin/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/javalin/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/jupyter-postgres/.github/workflows/deploy.yaml b/samples/jupyter-postgres/.github/workflows/deploy.yaml deleted file mode 100644 index 484a3651..00000000 --- a/samples/jupyter-postgres/.github/workflows/deploy.yaml +++ /dev/null @@ -1,26 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - with: - config-env-vars: POSTGRES_PASSWORD JUPYTER_TOKEN - uses: DefangLabs/defang-github-action@v1.3.2 - env: - POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }} - JUPYTER_TOKEN: ${{ secrets.JUPYTER_TOKEN }} diff --git a/samples/langchain/.github/workflows/deploy.yaml b/samples/langchain/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/langchain/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/managed-llm-provider/.github/workflows/deploy.yaml b/samples/managed-llm-provider/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/managed-llm-provider/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/managed-llm/.github/workflows/deploy.yaml b/samples/managed-llm/.github/workflows/deploy.yaml deleted file mode 100644 index f0166831..00000000 --- a/samples/managed-llm/.github/workflows/deploy.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 - with: - config-env-vars: MODEL - env: - MODEL: ${{ secrets.MODEL }} diff --git a/samples/mastra-nextjs/.github/workflows/deploy.yaml b/samples/mastra-nextjs/.github/workflows/deploy.yaml deleted file mode 100644 index a966ac05..00000000 --- a/samples/mastra-nextjs/.github/workflows/deploy.yaml +++ /dev/null @@ -1,28 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 - with: - config-env-vars: DB_SSL POSTGRES_PASSWORD LLM_MODEL GITHUB_TOKEN - env: - DB_SSL: ${{ secrets.DB_SSL }} - POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }} - LLM_MODEL: ${{ secrets.LLM_MODEL }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/samples/mcp/.github/workflows/deploy.yaml b/samples/mcp/.github/workflows/deploy.yaml deleted file mode 100644 index 20049971..00000000 --- a/samples/mcp/.github/workflows/deploy.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 - with: - config-env-vars: ANTHROPIC_API_KEY - env: - ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} diff --git a/samples/metabase/.github/workflows/deploy.yaml b/samples/metabase/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/metabase/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/n8n/.github/workflows/deploy.yaml b/samples/n8n/.github/workflows/deploy.yaml deleted file mode 100644 index 26121bd6..00000000 --- a/samples/n8n/.github/workflows/deploy.yaml +++ /dev/null @@ -1,28 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 - with: - config-env-vars: POSTGRES_USER N8N_ENCRYPTION_KEY DB_POSTGRESDB_SSL_ENABLED DB_POSTGRESDB_SSL_REJECT_UNAUTHORIZED - env: - POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }} - N8N_ENCRYPTION_KEY: ${{ secrets.N8N_ENCRYPTION_KEY }} - DB_POSTGRESDB_SSL_ENABLED: ${{ secrets.DB_POSTGRESDB_SSL_ENABLED }} - DB_POSTGRESDB_SSL_REJECT_UNAUTHORIZED: ${{ secrets.DB_POSTGRESDB_SSL_REJECT_UNAUTHORIZED }} diff --git a/samples/nextjs-blog/.github/workflows/deploy.yaml b/samples/nextjs-blog/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/nextjs-blog/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/nextjs-claude/.github/workflows/deploy.yaml b/samples/nextjs-claude/.github/workflows/deploy.yaml deleted file mode 100644 index 20049971..00000000 --- a/samples/nextjs-claude/.github/workflows/deploy.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 - with: - config-env-vars: ANTHROPIC_API_KEY - env: - ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} diff --git a/samples/nextjs-cv/.github/workflows/deploy.yaml b/samples/nextjs-cv/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/nextjs-cv/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/nextjs-documentation/.github/workflows/deploy.yaml b/samples/nextjs-documentation/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/nextjs-documentation/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/nextjs-postgres/.github/workflows/deploy.yaml b/samples/nextjs-postgres/.github/workflows/deploy.yaml deleted file mode 100644 index 936f784c..00000000 --- a/samples/nextjs-postgres/.github/workflows/deploy.yaml +++ /dev/null @@ -1,26 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 - with: - config-env-vars: POSTGRES_PASSWORD POSTGRES_SSL - env: - POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }} - POSTGRES_SSL: ${{ secrets.POSTGRES_SSL }} diff --git a/samples/nextjs-railpack/.github/workflows/deploy.yaml b/samples/nextjs-railpack/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/nextjs-railpack/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/nextjs/.github/workflows/deploy.yaml b/samples/nextjs/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/nextjs/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/nocodb/.github/workflows/deploy.yaml b/samples/nocodb/.github/workflows/deploy.yaml deleted file mode 100644 index 602c143a..00000000 --- a/samples/nocodb/.github/workflows/deploy.yaml +++ /dev/null @@ -1,30 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 - with: - config-env-vars: NC_DB NC_S3_ENDPOINT NC_S3_BUCKET_NAME NC_S3_REGION NC_S3_ACCESS_KEY NC_S3_ACCESS_SECRET - env: - NC_DB: ${{ secrets.NC_DB }} - NC_S3_ENDPOINT: ${{ secrets.NC_S3_ENDPOINT }} - NC_S3_BUCKET_NAME: ${{ secrets.NC_S3_BUCKET_NAME }} - NC_S3_REGION: ${{ secrets.NC_S3_REGION }} - NC_S3_ACCESS_KEY: ${{ secrets.NC_S3_ACCESS_KEY }} - NC_S3_ACCESS_SECRET: ${{ secrets.NC_S3_ACCESS_SECRET }} diff --git a/samples/nodejs-chatroom/.github/workflows/deploy.yaml b/samples/nodejs-chatroom/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/nodejs-chatroom/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/nodejs-express/.github/workflows/deploy.yaml b/samples/nodejs-express/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/nodejs-express/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/nodejs-form/.github/workflows/deploy.yaml b/samples/nodejs-form/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/nodejs-form/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/nodejs-http/.github/workflows/deploy.yaml b/samples/nodejs-http/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/nodejs-http/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/nodejs-openai/.github/workflows/deploy.yaml b/samples/nodejs-openai/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/nodejs-openai/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/nodejs-react-postgres/.github/workflows/deploy.yaml b/samples/nodejs-react-postgres/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/nodejs-react-postgres/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/nodejs-rest-api/.github/workflows/deploy.yaml b/samples/nodejs-rest-api/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/nodejs-rest-api/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/nodejs-s3/.github/workflows/deploy.yaml b/samples/nodejs-s3/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/nodejs-s3/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/nounly/.github/workflows/deploy.yaml b/samples/nounly/.github/workflows/deploy.yaml deleted file mode 100644 index 4e45ea9f..00000000 --- a/samples/nounly/.github/workflows/deploy.yaml +++ /dev/null @@ -1,26 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 - with: - config-env-vars: PROJECT_HONEYPOT_KEY SHARED_SECRETS - env: - PROJECT_HONEYPOT_KEY: ${{ secrets.PROJECT_HONEYPOT_KEY }} - SHARED_SECRETS: ${{ secrets.SHARED_SECRETS }} diff --git a/samples/ollama/.github/workflows/deploy.yaml b/samples/ollama/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/ollama/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/phoenix-postgres/.github/workflows/deploy.yaml b/samples/phoenix-postgres/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/phoenix-postgres/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/platformatic/.github/workflows/deploy.yaml b/samples/platformatic/.github/workflows/deploy.yaml deleted file mode 100644 index 326b10d9..00000000 --- a/samples/platformatic/.github/workflows/deploy.yaml +++ /dev/null @@ -1,20 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/python-form/.github/workflows/deploy.yaml b/samples/python-form/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/python-form/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/python-implicit-gpu/.github/workflows/deploy.yaml b/samples/python-implicit-gpu/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/python-implicit-gpu/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/python-minimal/.github/workflows/deploy.yaml b/samples/python-minimal/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/python-minimal/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/python-openai/.github/workflows/deploy.yaml b/samples/python-openai/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/python-openai/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/python-rest-api/.github/workflows/deploy.yaml b/samples/python-rest-api/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/python-rest-api/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/python-s3/.github/workflows/deploy.yaml b/samples/python-s3/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/python-s3/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/rails/.github/workflows/deploy.yaml b/samples/rails/.github/workflows/deploy.yaml deleted file mode 100644 index f6dcdc01..00000000 --- a/samples/rails/.github/workflows/deploy.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 - with: - config-env-vars: POSTGRES_PASSWORD - env: - POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }} diff --git a/samples/react-vite-railpack/.github/workflows/deploy.yaml b/samples/react-vite-railpack/.github/workflows/deploy.yaml deleted file mode 100644 index 179979b8..00000000 --- a/samples/react-vite-railpack/.github/workflows/deploy.yaml +++ /dev/null @@ -1,20 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 \ No newline at end of file diff --git a/samples/react/.github/workflows/deploy.yaml b/samples/react/.github/workflows/deploy.yaml deleted file mode 100644 index 179979b8..00000000 --- a/samples/react/.github/workflows/deploy.yaml +++ /dev/null @@ -1,20 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 \ No newline at end of file diff --git a/samples/redis-js/.github/workflows/deploy.yaml b/samples/redis-js/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/redis-js/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/rocket/.github/workflows/deploy.yaml b/samples/rocket/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/rocket/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/sailsjs-postgres/.github/workflows/deploy.yaml b/samples/sailsjs-postgres/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/sailsjs-postgres/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/sailsjs/.github/workflows/deploy.yaml b/samples/sailsjs/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/sailsjs/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/svelte-mysql/.github/workflows/deploy.yaml b/samples/svelte-mysql/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/svelte-mysql/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/sveltekit-mongodb/.github/workflows/deploy.yaml b/samples/sveltekit-mongodb/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/sveltekit-mongodb/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/sveltekit/.github/workflows/deploy.yaml b/samples/sveltekit/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/sveltekit/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/vllm/.github/workflows/deploy.yaml b/samples/vllm/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/vllm/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/samples/vuejs/.github/workflows/deploy.yaml b/samples/vuejs/.github/workflows/deploy.yaml deleted file mode 100644 index b3d14678..00000000 --- a/samples/vuejs/.github/workflows/deploy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy - -on: - push: - branches: - - main - -jobs: - deploy: - environment: production - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Deploy - uses: DefangLabs/defang-github-action@v1.3.2 diff --git a/scripts/package-lock.json b/scripts/package-lock.json index 5c2aeb0e..5ecc6d13 100644 --- a/scripts/package-lock.json +++ b/scripts/package-lock.json @@ -7,7 +7,8 @@ "dependencies": { "@actions/core": "^1.10.1", "@actions/github": "^6.0.0", - "@octokit/rest": "^20.1.1" + "@octokit/rest": "^20.1.1", + "yaml": "^2.4.0" } }, "node_modules/@actions/core": { @@ -59,6 +60,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.0.tgz", "integrity": "sha512-1LFfa/qnMQvEOAdzlQymH0ulepxbxnCYAKJZfMci/5XJyIHWgEYnDmgnKakbTh7CH2tFQ5O60oYDvns4i9RAIg==", + "peer": true, "dependencies": { "@octokit/auth-token": "^4.0.0", "@octokit/graphql": "^7.1.0", @@ -298,6 +300,21 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/yaml": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", + "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } } } } diff --git a/scripts/package.json b/scripts/package.json index 204d6af2..3cb49aa8 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -1,7 +1,11 @@ { + "scripts": { + "test": "node --test workflow-utils.test.js" + }, "dependencies": { "@actions/core": "^1.10.1", "@actions/github": "^6.0.0", - "@octokit/rest": "^20.1.1" + "@octokit/rest": "^20.1.1", + "yaml": "^2.4.0" } } diff --git a/scripts/template-manager.js b/scripts/template-manager.js index b6630bae..2c0bdbd8 100644 --- a/scripts/template-manager.js +++ b/scripts/template-manager.js @@ -1,6 +1,69 @@ const path = require('path'); const fs = require('fs'); const { execSync } = require('child_process'); +const { + extractSecretsFromCompose, + generateWorkflow, + loadWorkflowTemplate +} = require('./workflow-utils'); + +// Load canonical workflow template +const WORKFLOW_TEMPLATE = loadWorkflowTemplate(); + +const DRY_RUN = process.env.DRY_RUN === 'true'; + +/** + * Generate workflow for a sample directory (reads compose.yaml from path) + */ +function generateWorkflowForSample(samplePath) { + const composePaths = ['compose.yaml', 'compose.yml']; + let composeContent = null; + + for (const file of composePaths) { + const fullPath = path.join(samplePath, file); + if (fs.existsSync(fullPath)) { + composeContent = fs.readFileSync(fullPath, 'utf8'); + break; + } + } + + if (!composeContent) { + return generateWorkflow(WORKFLOW_TEMPLATE, { random: [], userProvided: [] }); + } + + const secrets = extractSecretsFromCompose(composeContent); + return { workflow: generateWorkflow(WORKFLOW_TEMPLATE, secrets), secrets }; +} + +/** + * Update the workflow file based on compose.yaml in the current directory + */ +function updateWorkflowFromCompose() { + // Read compose.yaml (try both .yaml and .yml) + let composeContent = null; + const composePaths = ['compose.yaml', 'compose.yml']; + + for (const composePath of composePaths) { + if (fs.existsSync(composePath)) { + composeContent = fs.readFileSync(composePath, 'utf8'); + break; + } + } + + if (!composeContent) { + console.log('No compose.yaml found, using template as-is'); + return generateWorkflow(WORKFLOW_TEMPLATE, { random: [], userProvided: [] }); + } + + // Extract secrets and generate workflow + const secrets = extractSecretsFromCompose(composeContent); + + if (secrets.random.length > 0 || secrets.userProvided.length > 0) { + console.log(`Found secrets - random: [${secrets.random.join(', ')}], user: [${secrets.userProvided.join(', ')}]`); + } + + return generateWorkflow(WORKFLOW_TEMPLATE, secrets); +} /** * This function returns the value of the client payload from the context. @@ -43,6 +106,69 @@ module.exports = async ({ github, context, core }) => { return; } + const modifiedSamples = modified.split('\n').map(s => s.split('/')?.[1]); + + // Dry-run mode: show diff between current and generated workflows + if (DRY_RUN) { + console.log('@@ DRY RUN MODE - showing workflow diffs\n'); + const templateOrg = 'DefangSamples'; + + for (const sample of modifiedSamples) { + const templateRepoName = `sample-${sample}-template`; + const samplePath = path.join('samples', sample); + const { workflow: newWorkflow, secrets } = generateWorkflowForSample(samplePath); + + console.log(`\n${'='.repeat(60)}`); + console.log(`# Sample: ${sample}`); + if (secrets?.random?.length > 0) { + console.log(`# Random secrets: ${secrets.random.join(', ')}`); + } + if (secrets?.userProvided?.length > 0) { + console.log(`# User-provided secrets: ${secrets.userProvided.join(', ')}`); + } + console.log(`${'='.repeat(60)}`); + + // Fetch current workflow from template repo + let currentWorkflow = null; + try { + const response = await github.rest.repos.getContent({ + owner: templateOrg, + repo: templateRepoName, + path: '.github/workflows/deploy.yaml' + }); + currentWorkflow = Buffer.from(response.data.content, 'base64').toString(); + } catch (err) { + if (err.status === 404) { + console.log('(new repo - no existing workflow)\n'); + console.log(newWorkflow); + continue; + } + throw err; + } + + // Show diff + if (currentWorkflow === newWorkflow) { + console.log('(no changes)\n'); + } else { + const currentLines = currentWorkflow.split('\n'); + const newLines = newWorkflow.split('\n'); + + console.log(''); + // Simple unified diff + for (let i = 0; i < Math.max(currentLines.length, newLines.length); i++) { + const curr = currentLines[i]; + const next = newLines[i]; + if (curr !== next) { + if (curr !== undefined) console.log(`- ${curr}`); + if (next !== undefined) console.log(`+ ${next}`); + } + } + console.log(''); + } + } + return { modifiedSamples, dryRun: true }; + } + const currentBranch = process.env.GITHUB_HEAD_REF.split('/').pop() || 'main'; const isMain = currentBranch === 'main'; const remoteBranch = isMain ? 'main' : `pr-test/${currentBranch}`; @@ -66,8 +192,6 @@ module.exports = async ({ github, context, core }) => { const repoNames = repos.map(r => r.name); console.log('@@ repos: ', repoNames); - const modifiedSamples = modified.split('\n').map(s => s.split('/')?.[1]) - // for each sample, create or update the template repo for (const sample of modifiedSamples) { const templateRepoName = `sample-${sample}-template`; @@ -106,6 +230,31 @@ module.exports = async ({ github, context, core }) => { const stdout2 = execSync(`git checkout ${splitBranch}`); console.log(`stdout: ${stdout2.toString()}`); + // Generate workflow from compose.yaml and write it + console.log(`@@ Generating workflow from compose.yaml`); + const workflowContent = updateWorkflowFromCompose(); + const workflowDir = '.github/workflows'; + const workflowPath = `${workflowDir}/deploy.yaml`; + + // Ensure directory exists + if (!fs.existsSync(workflowDir)) { + fs.mkdirSync(workflowDir, { recursive: true }); + } + + // Write the generated workflow + fs.writeFileSync(workflowPath, workflowContent); + console.log(`@@ Wrote workflow to ${workflowPath}`); + + // Stage and commit the workflow change + execSync(`git add ${workflowPath}`); + try { + execSync(`git commit --amend --no-edit`); + console.log(`@@ Amended commit with generated workflow`); + } catch (commitErr) { + // If amend fails (no changes), that's ok + console.log(`@@ No workflow changes to commit`); + } + if (isNew) { console.log(`@@ is ${sample} new? ${isNew} - Pushing to main branch`); const stdout4 = execSync(`git push ${authedRemote} ${splitBranch}:main --force`); @@ -128,4 +277,4 @@ module.exports = async ({ github, context, core }) => { modifiedSamples, repos } -} \ No newline at end of file +} diff --git a/scripts/update-template-workflows.js b/scripts/update-template-workflows.js new file mode 100644 index 00000000..2ca76b75 --- /dev/null +++ b/scripts/update-template-workflows.js @@ -0,0 +1,136 @@ +const { + extractSecretsFromCompose, + generateWorkflow, + loadWorkflowTemplate +} = require('./workflow-utils'); + +// Load canonical template +const TEMPLATE = loadWorkflowTemplate(); + +/** + * Get all repositories for an organization (paginated) + */ +async function getAllReposForOrg(github, org) { + let repos = []; + let page = 1; + + while (true) { + const response = await github.rest.repos.listForOrg({ + org: org, + type: 'public', + per_page: 100, + page: page + }); + + if (response.data.length === 0) break; + + repos = repos.concat(response.data); + page++; + } + + return repos; +} + +/** + * Update workflow files in all template repos + * + * @param {Object} args - The arguments object. + * @param {Object} args.github - The GitHub object. + * @param {import('@octokit/rest').Octokit} args.github.rest - The GitHub SDK instance. + * @param {import('@actions/github').Context} args.context - The context of the GitHub action. + * @param {import('@actions/core')} args.core - The core module from GitHub actions. + */ +module.exports = async ({ github, context, core }) => { + const templateOrg = 'DefangSamples'; + const repos = await getAllReposForOrg(github, templateOrg); + + console.log(`Found ${repos.length} repos in ${templateOrg}`); + + let updated = 0; + let skipped = 0; + let failed = 0; + + for (const repo of repos) { + if (!repo.name.endsWith('-template')) { + continue; + } + + try { + // Get compose.yaml to extract secrets + let composeContent = null; + try { + const response = await github.rest.repos.getContent({ + owner: templateOrg, + repo: repo.name, + path: 'compose.yaml' + }); + composeContent = Buffer.from(response.data.content, 'base64').toString(); + } catch (err) { + if (err.status === 404) { + console.log(`${repo.name}: no compose.yaml found, using template as-is`); + } else { + throw err; + } + } + + // Extract secrets from compose.yaml + const secrets = composeContent + ? extractSecretsFromCompose(composeContent) + : { random: [], userProvided: [] }; + + if (secrets.random.length > 0 || secrets.userProvided.length > 0) { + console.log(`${repo.name}: found secrets - random: [${secrets.random.join(', ')}], user: [${secrets.userProvided.join(', ')}]`); + } + + // 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; + } + throw err; + } + + const currentContent = Buffer.from(currentFile.content, 'base64').toString(); + + // Only update if changed + if (currentContent === updatedContent) { + 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`); + updated++; + } catch (err) { + console.error(`${repo.name}: failed - ${err.message}`); + failed++; + } + } + + console.log(`\nSummary: ${updated} updated, ${skipped} skipped, ${failed} failed`); + + return { updated, skipped, failed }; +}; diff --git a/scripts/workflow-utils.js b/scripts/workflow-utils.js new file mode 100644 index 00000000..730efe9f --- /dev/null +++ b/scripts/workflow-utils.js @@ -0,0 +1,163 @@ +const fs = require('fs'); +const path = require('path'); +const yaml = require('yaml'); + +/** + * Determine if a secret should be auto-generated (random) or user-provided + * Random: passwords, secret keys, encryption keys + * User-provided: API keys, tokens, cloud credentials (AWS, GCP, etc.) + */ +function isRandomSecret(name) { + const upper = name.toUpperCase(); + + // Cloud provider credentials are always user-provided + if (upper.startsWith('AWS_')) return false; + if (upper.startsWith('GCP_')) return false; + if (upper.startsWith('AZURE_')) return false; + + if (upper.includes('PASSWORD')) return true; + if (upper.includes('SECRET')) return true; + if (upper.includes('ENCRYPTION_KEY')) return true; + return false; +} + +/** + * Extract secrets from compose.yaml content + * Secrets are env vars with null value or array format without value + */ +function extractSecretsFromCompose(composeContent) { + const doc = yaml.parse(composeContent); + const secrets = new Set(); + + if (!doc?.services) return { random: [], userProvided: [] }; + + for (const service of Object.values(doc.services)) { + const env = service.environment; + if (!env) continue; + + if (Array.isArray(env)) { + // Array format: ["VAR1=value", "VAR2", "VAR3=${VAR3}", "URL=redis://$PASSWORD"] + // VAR2 (no =) is a secret, and any interpolated vars ($VAR or ${VAR}) are secrets + for (const item of env) { + if (typeof item !== 'string') continue; + + if (!item.includes('=')) { + // No value: "VAR" - definitely a secret + secrets.add(item); + } else { + // Has value - extract any interpolated variables + const value = item.substring(item.indexOf('=') + 1); + // Match $VAR or ${VAR} patterns + const matches = value.matchAll(/\$\{?([A-Z_][A-Z0-9_]*)\}?/gi); + for (const match of matches) { + secrets.add(match[1]); + } + } + } + } else if (typeof env === 'object') { + // Object format: { VAR1: "value", VAR2: null } - VAR2 is a secret + for (const [key, value] of Object.entries(env)) { + if (value === null) { + secrets.add(key); + } + } + } + } + + // Classify secrets + const random = []; + const userProvided = []; + + for (const secret of secrets) { + if (isRandomSecret(secret)) { + random.push(secret); + } else { + userProvided.push(secret); + } + } + + return { + random: random.sort(), + userProvided: userProvided.sort() + }; +} + +/** + * Find the first step that uses defang-github-action (the deploy step, not summary) + */ +function findDefangDeployStep(doc) { + const jobs = doc.get('jobs'); + if (!jobs) return null; + + for (const job of jobs.items) { + const steps = job.value?.get('steps'); + if (!steps) continue; + + for (const step of steps.items) { + const uses = step.get('uses'); + const name = step.get('name'); + // Find the deploy step (not the summary step) + if (uses && typeof uses === 'string' && + uses.includes('defang-github-action') && + name && typeof name === 'string' && + name.toLowerCase().includes('defang') && + !name.toLowerCase().includes('summary')) { + return step; + } + } + } + return null; +} + +/** + * Generate workflow from template with secrets + */ +function generateWorkflow(template, secrets) { + const templateDoc = yaml.parseDocument(template); + const step = findDefangDeployStep(templateDoc); + + if (!step) { + console.warn('Could not find defang deploy step in template'); + return templateDoc.toString(); + } + + // Add config-vars-init-random if there are random secrets + if (secrets.random.length > 0) { + step.setIn(['with', 'config-vars-init-random'], secrets.random.join(' ')); + } + + // Add config-env-vars if there are user-provided secrets + if (secrets.userProvided.length > 0) { + step.setIn(['with', 'config-env-vars'], secrets.userProvided.join(' ')); + } + + // Add env block with all secrets + const allSecrets = [...secrets.random, ...secrets.userProvided]; + if (allSecrets.length > 0) { + const envMap = new yaml.YAMLMap(); + for (const secret of allSecrets) { + envMap.add(new yaml.Pair(secret, `\${{ secrets.${secret} }}`)); + } + step.set('env', envMap); + } + + return templateDoc.toString(); +} + +/** + * Load the canonical workflow template + */ +function loadWorkflowTemplate() { + return fs.readFileSync( + path.join(__dirname, '..', 'templates', 'deploy.yaml'), + 'utf8' + ); +} + +module.exports = { + isRandomSecret, + extractSecretsFromCompose, + findDefangDeployStep, + generateWorkflow, + loadWorkflowTemplate +}; diff --git a/scripts/workflow-utils.test.js b/scripts/workflow-utils.test.js new file mode 100644 index 00000000..648785c4 --- /dev/null +++ b/scripts/workflow-utils.test.js @@ -0,0 +1,250 @@ +const { describe, it } = require('node:test'); +const assert = require('node:assert'); +const { isRandomSecret, extractSecretsFromCompose, generateWorkflow } = require('./workflow-utils'); + +describe('isRandomSecret', () => { + it('should classify PASSWORD as random', () => { + assert.strictEqual(isRandomSecret('POSTGRES_PASSWORD'), true); + assert.strictEqual(isRandomSecret('DB_PASSWORD'), true); + assert.strictEqual(isRandomSecret('password'), true); + assert.strictEqual(isRandomSecret('MONGO_INITDB_ROOT_PASSWORD'), true); + }); + + it('should classify SECRET as random', () => { + assert.strictEqual(isRandomSecret('SECRET_KEY'), true); + assert.strictEqual(isRandomSecret('DJANGO_SECRET_KEY'), true); + assert.strictEqual(isRandomSecret('SESSION_SECRET'), true); + assert.strictEqual(isRandomSecret('SECRET_KEY_BASE'), true); + assert.strictEqual(isRandomSecret('NC_S3_ACCESS_SECRET'), true); + }); + + it('should classify ENCRYPTION_KEY as random', () => { + assert.strictEqual(isRandomSecret('N8N_ENCRYPTION_KEY'), true); + assert.strictEqual(isRandomSecret('ENCRYPTION_KEY'), true); + }); + + it('should classify API keys as user-provided', () => { + assert.strictEqual(isRandomSecret('OPENAI_API_KEY'), false); + assert.strictEqual(isRandomSecret('ANTHROPIC_API_KEY'), false); + assert.strictEqual(isRandomSecret('TAVILY_API_KEY'), false); + assert.strictEqual(isRandomSecret('MISTRAL_API_KEY'), false); + }); + + it('should classify tokens as user-provided', () => { + assert.strictEqual(isRandomSecret('GITHUB_TOKEN'), false); + assert.strictEqual(isRandomSecret('JUPYTER_TOKEN'), false); + }); + + it('should classify cloud credentials as user-provided', () => { + assert.strictEqual(isRandomSecret('AWS_ACCESS_KEY'), false); + assert.strictEqual(isRandomSecret('AWS_SECRET_KEY'), false); + assert.strictEqual(isRandomSecret('AWS_SECRET_ACCESS_KEY'), false); + assert.strictEqual(isRandomSecret('GCP_SERVICE_ACCOUNT'), false); + assert.strictEqual(isRandomSecret('AZURE_CLIENT_SECRET'), false); + assert.strictEqual(isRandomSecret('NC_S3_ACCESS_KEY'), false); + }); + + it('should classify misc config as user-provided', () => { + assert.strictEqual(isRandomSecret('MODEL'), false); + assert.strictEqual(isRandomSecret('ALLOWED_HOSTS'), false); + assert.strictEqual(isRandomSecret('SSL_MODE'), false); + }); +}); + +describe('extractSecretsFromCompose', () => { + it('should extract secrets with null values (object format)', () => { + const compose = ` +services: + app: + environment: + POSTGRES_PASSWORD: null + DJANGO_SECRET_KEY: null + DATABASE_URL: postgres://localhost +`; + const result = extractSecretsFromCompose(compose); + assert.deepStrictEqual(result.random, ['DJANGO_SECRET_KEY', 'POSTGRES_PASSWORD']); + assert.deepStrictEqual(result.userProvided, []); + }); + + it('should extract secrets without values (array format)', () => { + const compose = ` +services: + app: + environment: + - OPENAI_API_KEY + - DATABASE_URL=postgres://localhost +`; + const result = extractSecretsFromCompose(compose); + assert.deepStrictEqual(result.random, []); + assert.deepStrictEqual(result.userProvided, ['OPENAI_API_KEY']); + }); + + it('should extract interpolated secrets ($VAR and ${VAR} formats)', () => { + const compose = ` +services: + app: + environment: + - MISTRAL_API_KEY=\${MISTRAL_API_KEY} + - DATABASE_URL=redis://user:\$PASSWORD@host + - CONN_STRING=postgres://\${DB_USER}:\${DB_PASSWORD}@host + - STATIC_VAR=plain_value +`; + const result = extractSecretsFromCompose(compose); + assert.deepStrictEqual(result.random, ['DB_PASSWORD', 'PASSWORD']); + assert.deepStrictEqual(result.userProvided, ['DB_USER', 'MISTRAL_API_KEY']); + }); + + it('should handle mixed secret types', () => { + const compose = ` +services: + db: + environment: + POSTGRES_PASSWORD: null + app: + environment: + - OPENAI_API_KEY + - SECRET_KEY +`; + const result = extractSecretsFromCompose(compose); + assert.deepStrictEqual(result.random, ['POSTGRES_PASSWORD', 'SECRET_KEY']); + assert.deepStrictEqual(result.userProvided, ['OPENAI_API_KEY']); + }); + + it('should deduplicate secrets across services', () => { + const compose = ` +services: + app: + environment: + POSTGRES_PASSWORD: null + worker: + environment: + POSTGRES_PASSWORD: null +`; + const result = extractSecretsFromCompose(compose); + assert.deepStrictEqual(result.random, ['POSTGRES_PASSWORD']); + assert.deepStrictEqual(result.userProvided, []); + }); + + it('should return empty arrays when no secrets', () => { + const compose = ` +services: + app: + environment: + DATABASE_URL: postgres://localhost + PORT: "3000" +`; + const result = extractSecretsFromCompose(compose); + assert.deepStrictEqual(result.random, []); + assert.deepStrictEqual(result.userProvided, []); + }); + + it('should handle services without environment', () => { + const compose = ` +services: + app: + image: nginx +`; + const result = extractSecretsFromCompose(compose); + assert.deepStrictEqual(result.random, []); + assert.deepStrictEqual(result.userProvided, []); + }); + + it('should handle empty compose', () => { + const result = extractSecretsFromCompose(''); + assert.deepStrictEqual(result.random, []); + assert.deepStrictEqual(result.userProvided, []); + }); + + // Real-world test cases from samples + it('should handle crewai compose', () => { + const compose = ` +services: + postgres: + environment: + POSTGRES_PASSWORD: null + app: + environment: + DJANGO_SECRET_KEY: null + DATABASE_URL: postgres://localhost +`; + const result = extractSecretsFromCompose(compose); + assert.deepStrictEqual(result.random, ['DJANGO_SECRET_KEY', 'POSTGRES_PASSWORD']); + assert.deepStrictEqual(result.userProvided, []); + }); + + it('should handle langchain compose', () => { + const compose = ` +services: + langchain-app: + environment: + - OPENAI_KEY +`; + const result = extractSecretsFromCompose(compose); + assert.deepStrictEqual(result.random, []); + assert.deepStrictEqual(result.userProvided, ['OPENAI_KEY']); + }); + + it('should handle django-postgres compose', () => { + const compose = ` +services: + db: + environment: + - POSTGRES_PASSWORD + app: + environment: + - POSTGRES_PASSWORD + - SECRET_KEY + - ALLOWED_HOSTS +`; + const result = extractSecretsFromCompose(compose); + assert.deepStrictEqual(result.random, ['POSTGRES_PASSWORD', 'SECRET_KEY']); + assert.deepStrictEqual(result.userProvided, ['ALLOWED_HOSTS']); + }); +}); + +describe('generateWorkflow', () => { + const template = ` +name: Deploy +on: + push: + branches: + - main +jobs: + defang: + runs-on: ubuntu-latest + steps: + - name: Checkout Repo + uses: actions/checkout@v4 + - name: Defang up + uses: DefangLabs/defang-github-action@v1.4.0 + with: + command: up +`; + + it('should add config-vars-init-random for random secrets', () => { + const secrets = { random: ['POSTGRES_PASSWORD'], userProvided: [] }; + const result = generateWorkflow(template, secrets); + assert.ok(result.includes('config-vars-init-random: POSTGRES_PASSWORD')); + }); + + it('should add config-env-vars for user-provided secrets', () => { + const secrets = { random: [], userProvided: ['OPENAI_API_KEY'] }; + const result = generateWorkflow(template, secrets); + assert.ok(result.includes('config-env-vars: OPENAI_API_KEY')); + }); + + it('should add env block with secrets', () => { + const secrets = { random: ['PASSWORD'], userProvided: ['API_KEY'] }; + const result = generateWorkflow(template, secrets); + assert.ok(result.includes('PASSWORD: ${{ secrets.PASSWORD }}')); + assert.ok(result.includes('API_KEY: ${{ secrets.API_KEY }}')); + }); + + it('should not modify template when no secrets', () => { + const secrets = { random: [], userProvided: [] }; + const result = generateWorkflow(template, secrets); + assert.ok(!result.includes('config-vars-init-random')); + assert.ok(!result.includes('config-env-vars')); + assert.ok(!result.includes('env:')); + }); +}); diff --git a/samples/crewai/.github/workflows/deploy.yaml b/templates/deploy.yaml similarity index 73% rename from samples/crewai/.github/workflows/deploy.yaml rename to templates/deploy.yaml index f65c8187..b8b8900b 100644 --- a/samples/crewai/.github/workflows/deploy.yaml +++ b/templates/deploy.yaml @@ -8,7 +8,6 @@ on: inputs: action: description: "Whether to deploy up or down" - required: true default: "up" type: choice options: @@ -31,12 +30,7 @@ jobs: - name: Defang ${{ github.event.inputs.action || 'up' }} uses: DefangLabs/defang-github-action@v1.4.0 with: - cli-version: nightly # for config-vars-init-random - config-vars-init-random: DJANGO_SECRET_KEY POSTGRES_PASSWORD command: ${{ github.event.inputs.action || 'up' }} - env: - DJANGO_SECRET_KEY: ${{ secrets.DJANGO_SECRET_KEY }} - POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }} - name: Deployment Summary uses: DefangLabs/defang-github-action@v1.4.0 From 31fdfc0579d02fd760832e697bcf9ca1edcc0a19 Mon Sep 17 00:00:00 2001 From: Lionello Lunesu Date: Mon, 2 Feb 2026 21:15:25 -0800 Subject: [PATCH 2/5] fix: update checkout action version and improve install step for Defang --- .github/workflows/check-sample.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/check-sample.yml b/.github/workflows/check-sample.yml index 045c73d5..f20015c5 100644 --- a/.github/workflows/check-sample.yml +++ b/.github/workflows/check-sample.yml @@ -3,7 +3,7 @@ name: Check Samples on: pull_request: paths: - - 'samples/**' + - "samples/**" jobs: check_samples: @@ -13,19 +13,20 @@ jobs: pull-requests: write steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: # Fetch two to see changes in current commit fetch-depth: 2 - - name: Install Defang + - name: Install Defang (nightly) run: | eval "$(curl -fsSL s.defang.io/install)" + env: + DEFANG_INSTALL_VERSION: nightly - name: Run Checks id: checks run: | - eval "$(curl -fsSL s.defang.io/install)" ./scripts/check-sample-files.sh > checklist.txt ./scripts/check-modified-samples.sh > modified.txt echo "@@ MODIFIED @@" From 8efadd7a261c16c7e1731b6d149b2762f2119368 Mon Sep 17 00:00:00 2001 From: jordanstephens Date: Tue, 3 Feb 2026 15:20:21 -0800 Subject: [PATCH 3/5] add stack to manual workflow dispatch inputs --- templates/deploy.yaml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/templates/deploy.yaml b/templates/deploy.yaml index b8b8900b..d97a9339 100644 --- a/templates/deploy.yaml +++ b/templates/deploy.yaml @@ -8,15 +8,19 @@ on: inputs: action: description: "Whether to deploy up or down" + required: true default: "up" type: choice options: - up - down + stack: + description: "The stack to deploy up or down. (Leave blank for default)" + default: "" jobs: defang: - name: Defang ${{ github.event.inputs.action || 'up' }} + name: Defang ${{ github.event.inputs.action || 'up' }} ${{ github.event.inputs.stack || 'default stack' }} environment: production runs-on: ubuntu-latest permissions: @@ -27,12 +31,14 @@ jobs: - name: Checkout Repo uses: actions/checkout@v4 - - name: Defang ${{ github.event.inputs.action || 'up' }} + - name: Defang ${{ github.event.inputs.action || 'up' }} ${{ github.event.inputs.stack || 'default stack' }} uses: DefangLabs/defang-github-action@v1.4.0 with: command: ${{ github.event.inputs.action || 'up' }} + stack: ${{ github.event.inputs.stack || '' }} - name: Deployment Summary uses: DefangLabs/defang-github-action@v1.4.0 with: command: services + stack: ${{ github.event.inputs.stack || '' }} From ccf3aac295c75a475ad5484540567c032001cbf1 Mon Sep 17 00:00:00 2001 From: jordanstephens Date: Tue, 3 Feb 2026 15:20:27 -0800 Subject: [PATCH 4/5] add concurrency group --- templates/deploy.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/templates/deploy.yaml b/templates/deploy.yaml index d97a9339..de261246 100644 --- a/templates/deploy.yaml +++ b/templates/deploy.yaml @@ -27,6 +27,10 @@ jobs: contents: read id-token: write + concurrency: + cancel-in-progress: false + group: deploy-${{ github.event.inputs.stack || 'default' }} + steps: - name: Checkout Repo uses: actions/checkout@v4 From 6db203981aeea87b0231e673594f9502f5e5c0bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lio=E6=9D=8E=E6=AD=90?= Date: Tue, 3 Feb 2026 15:31:18 -0800 Subject: [PATCH 5/5] Potential fix for code scanning alert no. 74: Workflow does not contain permissions [no ci] Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- .github/workflows/test-scripts.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/test-scripts.yml b/.github/workflows/test-scripts.yml index 6293f6e9..da6a5f05 100644 --- a/.github/workflows/test-scripts.yml +++ b/.github/workflows/test-scripts.yml @@ -1,5 +1,8 @@ name: Test Scripts +permissions: + contents: read + on: pull_request: paths: