diff --git a/.github/workflows/deploy-worker.yml b/.github/workflows/deploy-worker.yml index d1b0617..0457a78 100644 --- a/.github/workflows/deploy-worker.yml +++ b/.github/workflows/deploy-worker.yml @@ -13,24 +13,34 @@ on: commit: description: "Git commit hash" required: true + branch: + description: "Git branch" + required: true directory: description: "Directory to deploy" required: false + default: "." permissions: contents: read jobs: + notify: + runs-on: ubuntu-latest + steps: + - name: ${{github.event.inputs.appId}} + run: echo run identifier ${{ github.run_id }} + deploy: runs-on: ubuntu-latest + outputs: + worker-script: ${{ steps.get-script.outputs.worker-script-filename }} env: wranglerVersion: "3.68.0" outDir: "codius-dist" steps: - - name: ${{github.event.inputs.appId}} - run: echo run identifier ${{ github.run_id }} - name: Checkout uses: actions/checkout@v4 with: @@ -44,7 +54,7 @@ jobs: file_path="${directory:+${directory}/}pnpm-lock.yaml" if [ -f "$file_path" ]; then echo "PNPM lock file found" - echo "::set-output name=setup_pnpm::true" + echo "setup_pnpm=true" >> "$GITHUB_OUTPUT" fi - name: Setup Node.js @@ -71,8 +81,8 @@ jobs: id: check-custom-build working-directory: ${{ github.event.inputs.directory }} run: | - CUSTOM_BUILD=$(docker run -i ghcr.io/pelletier/go-toml:v2 tomljson < wrangler.toml | jq -e '.build' > /dev/null && echo "true" || echo "false") - echo "CUSTOM_BUILD=${CUSTOM_BUILD}" >> "$GITHUB_OUTPUT" + custom_build=$(docker run -i ghcr.io/pelletier/go-toml:v2 tomljson < wrangler.toml | jq -e '.build' > /dev/null && echo "true" || echo "false") + echo "custom-build=${custom_build}" >> "$GITHUB_OUTPUT" - name: Bundle/Build Worker uses: cloudflare/wrangler-action@v3 @@ -81,7 +91,7 @@ jobs: workingDirectory: ${{ github.event.inputs.directory }} command: deploy --dry-run ${{ env.OUT_DIR }} --name=${{ github.event.inputs.appId }} --dispatch-namespace ${{ github.event.inputs.dispatchNamespace }} env: - OUT_DIR: ${{ steps.check-custom-build.outputs.CUSTOM_BUILD == 'false' && format('--outdir={0}', env.outDir) || '' }} + OUT_DIR: ${{ steps.check-custom-build.outputs.custom-build == 'false' && format('--outdir={0}', env.outDir) || '' }} - name: Determine worker entry script id: get-script @@ -90,7 +100,7 @@ jobs: wrangler_main=$(docker run -i ghcr.io/pelletier/go-toml:v2 tomljson < wrangler.toml | jq -r '.main') echo "wrangler_main: $wrangler_main" - if [ "${{ steps.check-custom-build.outputs.CUSTOM_BUILD }}" == "false" ]; then + if [ "${{ steps.check-custom-build.outputs.custom-build }}" == "false" ]; then trimmed_wrangler_main=$(echo ${wrangler_main} | sed 's|^\./||') echo "Custom build is false; looking for the bundled script in ${outDir} containing // ${trimmed_wrangler_main}" worker_script=$(grep -rl "// ${trimmed_wrangler_main}" "${{ env.outDir }}" | head -n 1) @@ -101,11 +111,17 @@ jobs: fi if [ -z "$worker_script" ]; then - echo "Error: WORKER_SCRIPT is empty!" + echo "Error: Unable to find worker script!" exit 1 fi - echo "WORKER_SCRIPT=${worker_script}" >> "$GITHUB_OUTPUT" + echo "worker-script=${worker_script}" >> "$GITHUB_OUTPUT" + echo "worker-script-filename=$(basename $worker_script)" >> "$GITHUB_OUTPUT" + + - uses: actions/upload-artifact@v4 + with: + name: ${{ github.event.inputs.appId }} + path: ${{ github.event.inputs.directory }}/${{ steps.get-script.outputs.worker-script }} - name: Deploy Worker uses: cloudflare/wrangler-action@v3 @@ -114,4 +130,36 @@ jobs: accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} wranglerVersion: ${{ env.wranglerVersion }} workingDirectory: ${{ github.event.inputs.directory }} - command: deploy --no-bundle --name=${{ github.event.inputs.appId }} --dispatch-namespace ${{ github.event.inputs.dispatchNamespace }} ${{ steps.get-script.outputs.WORKER_SCRIPT }} + command: deploy --no-bundle --name=${{ github.event.inputs.appId }} --dispatch-namespace ${{ github.event.inputs.dispatchNamespace }} ${{ steps.get-script.outputs.worker-script }} + + attest: + needs: deploy + runs-on: ubuntu-latest + + permissions: + id-token: write + attestations: write + + steps: + - name: Download worker script + uses: actions/download-artifact@v4 + with: + name: ${{ github.event.inputs.appId }} + + - uses: actions/attest-build-provenance/predicate@d58ddf9f241cd8163408934540d01c3335864d64 # predicate@1.1.2 + id: generate-build-provenance-predicate + + - name: Update Predicate JSON + id: update-predicate + run: | + uri="git+https://github.com/${{ github.event.inputs.repo }}@refs/heads/${{ github.event.inputs.branch }}" + resolved_dependencies=$(jq -n --arg uri "$uri" --arg commit "${{ github.event.inputs.commit }}" --arg path "${{ github.event.inputs.directory }}" '[{"uri": $uri, "digest": {"gitCommit": $commit}, "path": $path}]') + predicate=$(echo '${{ steps.generate-build-provenance-predicate.outputs.predicate }}' | jq -c '.buildDefinition.externalParameters.resolvedDependencies = $resolved_dependencies' --argjson resolved_dependencies "$resolved_dependencies") + echo "predicate=$predicate" >> $GITHUB_OUTPUT + + - uses: actions/attest@2da0b136720d14f01f4dbeeafd1d5a4d76cbe21d # v1.4.0 + id: attest + with: + subject-path: ${{ needs.deploy.outputs.worker-script }} + predicate-type: ${{ steps.generate-build-provenance-predicate.outputs.predicate-type }} + predicate: ${{ steps.update-predicate.outputs.predicate }} diff --git a/packages/codius-astro/README.md b/packages/codius-astro/README.md index 4216c82..67b3d5c 100644 --- a/packages/codius-astro/README.md +++ b/packages/codius-astro/README.md @@ -25,7 +25,7 @@ pnpm --filter codius-astro d1 migrations apply --remote > **Note:** Rollback local migrations by deleting the state files with the following command: > > ```bash -> rm .wrangler/state/v3/d1/miniflare-D1DatabaseObject/* +> rm packages/codius-astro/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/* > ``` ### Environment Variables diff --git a/packages/codius-astro/assets/webhook-event.png b/packages/codius-astro/assets/webhook-event.png index 33aab57..6eb9df0 100755 Binary files a/packages/codius-astro/assets/webhook-event.png and b/packages/codius-astro/assets/webhook-event.png differ diff --git a/packages/codius-astro/drizzle/0001_fearless_captain_flint.sql b/packages/codius-astro/drizzle/0001_fearless_captain_flint.sql new file mode 100644 index 0000000..80a8010 --- /dev/null +++ b/packages/codius-astro/drizzle/0001_fearless_captain_flint.sql @@ -0,0 +1,2 @@ +CREATE INDEX `idx_apps_github_workflow_run_id` ON `apps` (`github_workflow_run_id`);--> statement-breakpoint +ALTER TABLE `apps` DROP COLUMN `github_workflow_job_id`; \ No newline at end of file diff --git a/packages/codius-astro/drizzle/meta/0001_snapshot.json b/packages/codius-astro/drizzle/meta/0001_snapshot.json new file mode 100644 index 0000000..9e1a568 --- /dev/null +++ b/packages/codius-astro/drizzle/meta/0001_snapshot.json @@ -0,0 +1,356 @@ +{ + "version": "6", + "dialect": "sqlite", + "id": "57fb6080-4ec4-4c8b-bc82-712ed5c88cc6", + "prevId": "ca561cda-e276-4c9a-879e-c97d1d02d7d6", + "tables": { + "apps": { + "name": "apps", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "github_owner": { + "name": "github_owner", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "repo": { + "name": "repo", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "branch": { + "name": "branch", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "commit_hash": { + "name": "commit_hash", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "directory": { + "name": "directory", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'pending'" + }, + "github_workflow_run_id": { + "name": "github_workflow_run_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(unixepoch())" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(unixepoch())" + }, + "deleted_at": { + "name": "deleted_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "idx_apps_user_id": { + "name": "idx_apps_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + }, + "idx_apps_github_workflow_run_id": { + "name": "idx_apps_github_workflow_run_id", + "columns": [ + "github_workflow_run_id" + ], + "isUnique": false + }, + "apps_user_id_github_owner_repo_commit_hash_directory_deleted_at_unique": { + "name": "apps_user_id_github_owner_repo_commit_hash_directory_deleted_at_unique", + "columns": [ + "user_id", + "github_owner", + "repo", + "commit_hash", + "directory", + "deleted_at" + ], + "isUnique": true + } + }, + "foreignKeys": { + "apps_user_id_users_id_fk": { + "name": "apps_user_id_users_id_fk", + "tableFrom": "apps", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "payments": { + "name": "payments", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "amount": { + "name": "amount", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "stripe_checkout_session_id": { + "name": "stripe_checkout_session_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "app_id": { + "name": "app_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(unixepoch())" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(unixepoch())" + } + }, + "indexes": {}, + "foreignKeys": { + "payments_app_id_apps_id_fk": { + "name": "payments_app_id_apps_id_fk", + "tableFrom": "payments", + "tableTo": "apps", + "columnsFrom": [ + "app_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "payments_user_id_users_id_fk": { + "name": "payments_user_id_users_id_fk", + "tableFrom": "payments", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "sessions": { + "name": "sessions", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(unixepoch())" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(unixepoch())" + } + }, + "indexes": {}, + "foreignKeys": { + "sessions_user_id_users_id_fk": { + "name": "sessions_user_id_users_id_fk", + "tableFrom": "sessions", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "users": { + "name": "users", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "github_id": { + "name": "github_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(unixepoch())" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(unixepoch())" + } + }, + "indexes": { + "users_github_id_unique": { + "name": "users_github_id_unique", + "columns": [ + "github_id" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "internal": { + "indexes": {} + } +} \ No newline at end of file diff --git a/packages/codius-astro/drizzle/meta/_journal.json b/packages/codius-astro/drizzle/meta/_journal.json index eca5637..38c822d 100644 --- a/packages/codius-astro/drizzle/meta/_journal.json +++ b/packages/codius-astro/drizzle/meta/_journal.json @@ -8,6 +8,13 @@ "when": 1722449250619, "tag": "0000_tidy_nekra", "breakpoints": true + }, + { + "idx": 1, + "version": "6", + "when": 1724711940074, + "tag": "0001_fearless_captain_flint", + "breakpoints": true } ] } \ No newline at end of file diff --git a/packages/codius-astro/package.json b/packages/codius-astro/package.json index 8d9cf4d..1d14646 100644 --- a/packages/codius-astro/package.json +++ b/packages/codius-astro/package.json @@ -35,7 +35,7 @@ "class-variance-authority": "^0.7.0", "cloudflare": "^3.5.0", "clsx": "^2.1.1", - "drizzle-orm": "^0.31.4", + "drizzle-orm": "^0.33.0", "lucia": "^3.2.0", "lucide-react": "^0.399.0", "react": "^18.3.1", diff --git a/packages/codius-astro/src/actions/index.ts b/packages/codius-astro/src/actions/index.ts index 4a1247a..1fa2781 100644 --- a/packages/codius-astro/src/actions/index.ts +++ b/packages/codius-astro/src/actions/index.ts @@ -86,6 +86,7 @@ export const server = { owner, repo, commitHash: commit.sha, + branch, directory, dispatchNamespace: context.locals.runtime.env.CF_DISPATCH_NAMESPACE, }) diff --git a/packages/codius-astro/src/components/ViewWorkflowButton.astro b/packages/codius-astro/src/components/ViewWorkflowButton.astro index 0442ff4..20c0182 100644 --- a/packages/codius-astro/src/components/ViewWorkflowButton.astro +++ b/packages/codius-astro/src/components/ViewWorkflowButton.astro @@ -5,13 +5,12 @@ import { scope } from "simple:scope" type Props = { workflowRunId: number - workflowJobId: number } -const { workflowRunId, workflowJobId } = Astro.props +const { workflowRunId } = Astro.props --- - +