Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
564ec93
fix: add keys to deployment
paprikaf Dec 10, 2025
71182ed
fix: use process.env for Discogs secrets in deployed Workers
paprikaf Dec 10, 2025
f9a423e
fix: use cloudflare:workers env for accessing Worker secrets
paprikaf Dec 10, 2025
4f64b77
fix: add @cloudflare/workers-types for cloudflare:workers module
paprikaf Dec 10, 2025
14f4261
fix: allow preview URLs and use process.env for Discogs secrets
paprikaf Dec 10, 2025
804fd3e
debug: add endpoint to check env vars
paprikaf Dec 10, 2025
f2196f8
fix: use wrangler-action secrets param for Worker secrets
paprikaf Dec 10, 2025
18b5510
fix: use postCommands to set secrets with correct worker name
paprikaf Dec 10, 2025
0595c81
fix: install wrangler globally for postCommands
paprikaf Dec 10, 2025
40e9fd1
fix: use separate step for setting worker secrets
paprikaf Dec 10, 2025
6f00774
debug: check cloudflare env bindings for secrets
paprikaf Dec 10, 2025
bef9159
fix: expose Cloudflare env bindings to process.env in worker entry
paprikaf Dec 10, 2025
f235c74
fix: use cloudflare:workers import for accessing bindings
paprikaf Dec 10, 2025
4ee3d00
feat: update all Discogs API code to use cloudflare:workers bindings
paprikaf Dec 10, 2025
babf7ab
fix: add process.env fallback and .dev.vars for local development
paprikaf Dec 10, 2025
2b0e1b5
refactor: centralize Discogs env config and SDK creation
paprikaf Dec 10, 2025
b701053
fix: localhost
paprikaf Dec 10, 2025
d341527
fix: allow workers.dev URLs in OAuth origin validation
paprikaf Dec 10, 2025
6c3f337
chore: ignore local context-repos
paprikaf Dec 13, 2025
a299440
fix: harden Discogs OAuth error typing
paprikaf Dec 13, 2025
c0a76e9
fix: preview
paprikaf Dec 13, 2025
5d5c4a2
fix: Prevent Vite from crawling to local
paprikaf Dec 13, 2025
98b83c6
chore: add context-repos to prettier ignore
paprikaf Dec 13, 2025
e91b54f
ci: harden preview deploy and isolate context-repos
paprikaf Dec 13, 2025
a86c647
chorus: config
paprikaf Dec 13, 2025
a963deb
chore:update workflow
paprikaf Dec 13, 2025
f434e0b
chore: upgrade @crate.ai/discogs-sdk to 2.4.0 (Workers-compatible)
paprikaf Dec 13, 2025
3a13b3b
debug: add detailed logging to diagnose Discogs OAuth failure
paprikaf Dec 13, 2025
45b2cee
fix: ci
paprikaf Dec 13, 2025
b9322ac
debug: log credentials being passed to SDK
paprikaf Dec 13, 2025
f76dded
debug: log actual credential values being loaded
paprikaf Dec 13, 2025
eccc199
fix: format
paprikaf Dec 13, 2025
7541946
fix: add OAuth authentication when fetching Discogs user profile
paprikaf Dec 14, 2025
adb5153
fix
paprikaf Dec 14, 2025
8e2f036
fix: bump version
paprikaf Dec 14, 2025
0eb1e08
fix(discogs): handle OAuth handshake in app routes for Workers
paprikaf Dec 14, 2025
6f8700a
debug(discogs): return safe OAuth header diagnostics on failure
paprikaf Dec 14, 2025
146033b
fix(discogs): percent-encode oauth_signature in OAuth header
paprikaf Dec 14, 2025
dbfc807
fix: format
paprikaf Dec 14, 2025
bbd54c3
fix(discogs): send OAuth params in POST body (Workers-safe)
paprikaf Dec 14, 2025
7a1f77c
chore: format
paprikaf Dec 14, 2025
7eaeeb4
fix: bad conflict res
govi218 Dec 17, 2025
4b9d306
fix: add better observability for discogs route
govi218 Dec 17, 2025
1190e54
fix: swap to netlify
govi218 Dec 30, 2025
c276f33
fix: netflify index file
govi218 Jan 5, 2026
095d096
chore: netlify preset
govi218 Jan 5, 2026
73d2c2c
fix: add vite entry point for build
govi218 Jan 5, 2026
7b987a4
chore: try server side config
govi218 Jan 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"convex/_generated",
"routeTree.gen.ts",
"context-repos",
"__tests__"
"__tests__",
"context-repos"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/cleanup-preview.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ jobs:
cleanup:
name: Delete Preview Worker
runs-on: ubuntu-latest
concurrency:
group: preview-${{ github.event.pull_request.number }}
cancel-in-progress: true

steps:
- name: Delete Preview Worker
Expand All @@ -16,4 +19,3 @@ jobs:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: delete --name crate-app-pr-${{ github.event.pull_request.number }} --force

72 changes: 57 additions & 15 deletions .github/workflows/deploy-preview.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ jobs:
deploy:
name: Build & Deploy Preview
runs-on: ubuntu-latest
concurrency:
group: preview-${{ github.event.pull_request.number }}
cancel-in-progress: true

env:
WORKER_NAME: crate-app-pr-${{ github.event.pull_request.number }}

steps:
- name: Checkout
Expand All @@ -33,22 +39,61 @@ jobs:

- name: Build
env:
VITE_DISCOGS_CONSUMER_KEY: ${{ secrets.VITE_DISCOGS_CONSUMER_KEY }}
VITE_DISCOGS_CONSUMER_SECRET: ${{ secrets.VITE_DISCOGS_CONSUMER_SECRET }}
VITE_CONVEX_URL: ${{ secrets.VITE_CONVEX_URL }}
run: pnpm build

- name: Clean wrangler cache
run: rm -rf .wrangler

- name: Install Wrangler CLI
run: npm install -g wrangler

# Deploy first to ensure the Worker exists, then set secrets deterministically.
- name: Deploy Preview to Cloudflare Workers
id: deploy
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
workingDirectory: dist/server
command: deploy --name crate-app-pr-${{ github.event.pull_request.number }}
command: deploy --name ${{ env.WORKER_NAME }}

- name: Set Worker Secrets
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
run: |
echo "${{ secrets.VITE_DISCOGS_CONSUMER_KEY }}" | wrangler secret put DISCOGS_CONSUMER_KEY --name "$WORKER_NAME"
echo "${{ secrets.VITE_DISCOGS_CONSUMER_SECRET }}" | wrangler secret put DISCOGS_CONSUMER_SECRET --name "$WORKER_NAME"

- name: Smoke check Discogs runtime bindings
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
set -euo pipefail
URL="https://crate-app-pr-${PR_NUMBER}.govi218mu.workers.dev/api/auth/discogs/debug"
echo "Checking ${URL}"
# Give Workers a moment to apply secret updates
sleep 3

BODY="$(curl -fsSL --retry 15 --retry-all-errors --retry-delay 3 "${URL}")"
echo "Debug response: ${BODY}"

export BODY
node -e '
const json = JSON.parse(process.env.BODY || "{}");
const bindings = Array.isArray(json.availableBindings) ? json.availableBindings : [];
const ok =
json.hasCredentials === true &&
bindings.includes("DISCOGS_CONSUMER_KEY") &&
bindings.includes("DISCOGS_CONSUMER_SECRET");
if (!ok) {
console.error(json);
process.exit(1);
}
console.log("hasCredentials:", json.hasCredentials);
console.log("availableBindings:", bindings);
'

- name: Comment PR with Preview URL
uses: actions/github-script@v7
Expand All @@ -57,31 +102,29 @@ jobs:
const prNumber = context.payload.pull_request.number;
const previewUrl = `https://${prNumber}-pr.crate.audio`;
const fallbackUrl = `https://crate-app-pr-${prNumber}.govi218mu.workers.dev`;

// Find existing comment

const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
});

const botComment = comments.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('🚀 Preview Deployment')

const botComment = comments.find((comment) =>
comment.user.type === 'Bot' && comment.body.includes('🚀 Preview Deployment'),
);

const body = `## 🚀 Preview Deployment

| Environment | URL |
|-------------|-----|
| Preview | [${previewUrl}](${previewUrl}) |
| Fallback | [${fallbackUrl}](${fallbackUrl}) |

**Commit:** \`${context.sha.substring(0, 7)}\`
**Updated:** ${new Date().toISOString()}

> This preview will be automatically deleted when the PR is closed.`;

if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
Expand All @@ -97,4 +140,3 @@ jobs:
body,
});
}

13 changes: 11 additions & 2 deletions .github/workflows/deploy-production.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,14 @@ jobs:
- name: Build
env:
VITE_CONVEX_URL: ${{ secrets.VITE_CONVEX_URL }}
VITE_DISCOGS_CONSUMER_KEY: ${{ secrets.VITE_DISCOGS_CONSUMER_KEY }}
VITE_DISCOGS_CONSUMER_SECRET: ${{ secrets.VITE_DISCOGS_CONSUMER_SECRET }}
run: pnpm build

- name: Clean wrangler cache
run: rm -rf .wrangler

- name: Install Wrangler CLI
run: npm install -g wrangler

- name: Deploy to Cloudflare Workers (Production)
uses: cloudflare/wrangler-action@v3
with:
Expand All @@ -54,3 +55,11 @@ jobs:
workingDirectory: dist/server
command: deploy

- name: Set Worker Secrets
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
run: |
echo "${{ secrets.VITE_DISCOGS_CONSUMER_KEY }}" | wrangler secret put DISCOGS_CONSUMER_KEY --name crate-app
echo "${{ secrets.VITE_DISCOGS_CONSUMER_SECRET }}" | wrangler secret put DISCOGS_CONSUMER_SECRET --name crate-app

13 changes: 11 additions & 2 deletions .github/workflows/deploy-staging.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,14 @@ jobs:
- name: Build
env:
VITE_CONVEX_URL: ${{ secrets.VITE_CONVEX_URL }}
VITE_DISCOGS_CONSUMER_KEY: ${{ secrets.VITE_DISCOGS_CONSUMER_KEY }}
VITE_DISCOGS_CONSUMER_SECRET: ${{ secrets.VITE_DISCOGS_CONSUMER_SECRET }}
run: pnpm build

- name: Clean wrangler cache
run: rm -rf .wrangler

- name: Install Wrangler CLI
run: npm install -g wrangler

- name: Deploy to Cloudflare Workers (Staging)
uses: cloudflare/wrangler-action@v3
with:
Expand All @@ -54,3 +55,11 @@ jobs:
workingDirectory: dist/server
command: deploy

- name: Set Worker Secrets
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
run: |
echo "${{ secrets.VITE_DISCOGS_CONSUMER_KEY }}" | wrangler secret put DISCOGS_CONSUMER_KEY --name crate-app
echo "${{ secrets.VITE_DISCOGS_CONSUMER_SECRET }}" | wrangler secret put DISCOGS_CONSUMER_SECRET --name crate-app

6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,9 @@ context-repos/

# Cursor IDE rules
.cursor/
.dev.vars

# Context repositories (local reference repos, not part of the project)
context-repos/
# Local Netlify folder
.netlify
2 changes: 1 addition & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ node_modules/
pnpm-lock.yaml

# Context repos
context-repos/
context-repos/
47 changes: 47 additions & 0 deletions app/api/auth/discogs/debug.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { createFileRoute } from '@tanstack/react-router';
import {
getDiscogsCredentials,
hasDiscogsCredentials,
getEnvironment,
getCloudflareEnv,
} from '@/lib/config/env';

/**
* Debug endpoint for verifying Discogs credentials are properly configured.
*
* This endpoint is useful for:
* - Verifying secrets are loaded in production after deployment
* - Debugging local development setup
* - Checking .dev.vars is properly configured
*
* @route GET /api/auth/discogs/debug
*/
export const Route = createFileRoute('/api/auth/discogs/debug')({
server: {
handlers: {
GET: async ({ request }) => {
const origin = new URL(request.url).origin;
const { consumerKey, consumerSecret } = getDiscogsCredentials();
const cfEnv = getCloudflareEnv();

const debugInfo = {
origin,
hasCredentials: hasDiscogsCredentials(),
credentials: {
hasConsumerKey: !!consumerKey,
consumerKeyLength: consumerKey?.length || 0,
hasConsumerSecret: !!consumerSecret,
consumerSecretLength: consumerSecret?.length || 0,
// Show first 4 chars to verify correct key (safe to expose)
keyPrefix: consumerKey?.substring(0, 4) || 'N/A',
},
environment: getEnvironment() || 'not-set',
// List all available env keys (without values) for debugging
availableBindings: Object.keys(cfEnv),
};

return Response.json(debugInfo);
},
},
},
});
Loading
Loading