Skip to content

feat: add endpoint to upload encrypted AI configuration to Cloudflare KV #116

feat: add endpoint to upload encrypted AI configuration to Cloudflare KV

feat: add endpoint to upload encrypted AI configuration to Cloudflare KV #116

# Copyright (c) 2024-2026 Ronan LE MEILLAT
# License: AGPL-3.0-or-later
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
name: CloudflareWorkerDeploy
on:
push:
branches:
- main
paths:
- apps/merchant/**
- package-lock.json
- .github/workflows/deploy-cloudflare-worker.yaml
- .github/workflows/create-env-artifact.yaml
- scripts/generate-wrangler-jsonc.py
workflow_dispatch:
permissions:
contents: write
pages: write
id-token: write
packages: write
attestations: write
jobs:
create-env:
uses: ./.github/workflows/create-env-artifact.yaml
secrets: inherit
build:
needs: create-env
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
submodules: "recursive"
fetch-depth: 1
- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: "24"
- name: Cache Turborepo
uses: actions/cache@v5
with:
path: .turbo
key: ${{ runner.os }}-turbo-${{ github.sha }}
restore-keys: |
${{ runner.os }}-turbo-
- name: Install dependencies
run: |
npm install
- name: Download shared .env artifact
uses: actions/download-artifact@v5
with:
name: shared-env
path: .
# .env.enc was encrypted with openssl enc -aes-256-cbc -salt -in env_and_wrangler.tar.gz -out .env.enc -iter 10000 -pass pass:"${{ secrets.CRYPTOKEN }}"
# Decrypt it using the same key and parameters
- name: Decrypt .env + wrangler.jsonc artifact
run: |
openssl enc -aes-256-cbc -d -salt -in .env.enc -out env_and_wrangler.tar.gz -iter 10000 -pass pass:"${{ secrets.CRYPTOKEN }}"
tar -xzvf env_and_wrangler.tar.gz
rm env_and_wrangler.tar.gz .env.enc
if [ ! -f .env ]; then
echo "Decrypted artifact does not contain .env"
exit 1
fi
if [ ! -f apps/merchant/wrangler.jsonc ]; then
echo "Decrypted artifact does not contain apps/merchant/wrangler.jsonc"
exit 1
fi
if ! grep -q "AUTH0_DOMAIN=${{ secrets.AUTH0_DOMAIN }}" .env; then
echo "Decrypted .env file does not contain expected AUTH0_DOMAIN value"
exit 1
fi
- name: Set Wrangler secrets in bulk from secrets.json
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
run: |
# Check if secrets.json exists and is valid JSON
if [ ! -f apps/merchant/secrets.json ]; then
echo "secrets.json file not found in decrypted artifact"
exit 1
fi
cd apps/merchant
npx wrangler secret bulk < secrets.json
- name: Deploy
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
workingDirectory: apps/merchant
- name: Upload ai.json.enc to KV_CACHE
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
run: |
if [ ! -f ai.json.enc ]; then
echo "Warning: ai.json.enc not found. Skipping KV upload."
exit 0
fi
cd apps/merchant
npx wrangler kv key put --path ../../ai.json.enc --binding KV_CACHE --remote ai:config
echo "✓ ai.json.enc uploaded to KV_CACHE"