From a3cf73f967a318b8dcac85f8ae8d00b16059ea7a Mon Sep 17 00:00:00 2001 From: chronark Date: Sun, 3 Sep 2023 12:05:39 +0200 Subject: [PATCH] feat: stepci --- .github/workflows/deploy-agent.yaml | 52 ++++++++- apps/agent/e2e/workflow.json | 110 ++++++++++++++++++ .../(app)/app/keys/[keyId]/page.tsx | 9 +- .../app/keys/[keyId]/settings/delete-key.tsx | 1 - 4 files changed, 165 insertions(+), 7 deletions(-) create mode 100644 apps/agent/e2e/workflow.json diff --git a/.github/workflows/deploy-agent.yaml b/.github/workflows/deploy-agent.yaml index 0144506d1d..93af0d8653 100644 --- a/.github/workflows/deploy-agent.yaml +++ b/.github/workflows/deploy-agent.yaml @@ -63,8 +63,8 @@ jobs: tags: ${{ env.TAG }} build-args: VERSION=${{env.VERSION}} - deploy: - name: Deploy Agent + deploy_preview: + name: Deploy Preview runs-on: ubuntu-latest needs: - build @@ -93,9 +93,55 @@ jobs: env: FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} + integration_test_preview: + name: Integration Test + runs-on: ubuntu-latest + needs: + - deploy_preview + steps: + - uses: actions/checkout@v3 + - name: Step CI Action + uses: stepci/stepci@main + with: + workflow: "apps/agent/e2e/workflow.yml" + envs: "baseUrl=${{ secrets.PREVIEW_BASE_URL }} apiId=${{secrets.PREVIEW_API_ID}}" + secrets: "rootKey=${{ secrets.PREVIEW_ROOT_KEY }}" + + + deploy_production: + name: Deploy Production + runs-on: ubuntu-latest + if: "!github.event.release.prerelease" + needs: + - build + - deploy_preview + - integration_test_preview + steps: + - uses: actions/checkout@v3 + + - name: Get tag + run: echo "TAG=ghcr.io/${{ github.repository }}:$(git describe --tags --always)" > $GITHUB_ENV + + - name: Login to image repository + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Install flyctl + uses: superfly/flyctl-actions/setup-flyctl@master + + - name: Download image + run: docker pull ${{env.TAG}} + + + - name: Deploy prod - if: "!github.event.release.prerelease" run: flyctl -c="./fly.prod.toml" deploy --image=${{ env.TAG }} --strategy=canary working-directory: apps/agent env: FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} + + + diff --git a/apps/agent/e2e/workflow.json b/apps/agent/e2e/workflow.json new file mode 100644 index 0000000000..8452f41b82 --- /dev/null +++ b/apps/agent/e2e/workflow.json @@ -0,0 +1,110 @@ +{ + "version": "1.1", + "name": "Status Check", + "secrets": { + "rootKey": "from-cli" + }, + "env": { + "baseUrl": "https://api.unkey.dev", + "apiId": "api_J7MXWBmycyMoTALYkts6Nz" + }, + "config": { + "loadTest": { + "phases": [ + { + "duration": 10, + "arrivalRate": 1 + }, + { + "duration": 60, + "arrivalRate": 10 + } + ] + } + }, + "tests": { + "example": { + "steps": [ + { + "name": "Create Key", + "http": { + "url": "${{env.baseUrl}}/v1/keys", + "method": "POST", + "headers": { + "Content-Type": "application/json", + "Authorization": "Bearer ${{secrets.rootKey}}" + }, + "json": { + "apiId": "${{env.apiId}}" + }, + "check": { + "status": "/^20/", + "jsonpath": { + "$.keyId": [{ "isString": true }], + "$.key": [{ "isString": true }] + } + }, + "captures": { + "key": { + "jsonpath": "$.key" + }, + "keyId": { + "jsonpath": "$.keyId" + } + } + } + }, + { + "name": "Verify Key", + "http": { + "url": "${{env.baseUrl}}/v1/keys/verify", + "method": "POST", + "headers": { + "Content-Type": "application/json" + }, + "json": { + "key": "${{captures.key}}" + }, + "check": { + "status": "/^20/", + "jsonpath": { + "$.valid": true + } + } + } + }, + { + "name": "Random Invalid Key", + "http": { + "url": "${{env.baseUrl}}/v1/keys/verify", + "method": "POST", + "headers": { + "Content-Type": "application/json" + }, + "json": { + "key": "${{ | naughtystring }}" + }, + "check": { + "status": 200, + "jsonpath": { + "$.valid": false + }, + "performance": { + "firstByte": [ + { + "lte": 100 + } + ], + "total": [ + { + "lte": 200 + } + ] + } + } + } + } + ] + } + } +} diff --git a/apps/web/app/(authenticated)/(app)/app/keys/[keyId]/page.tsx b/apps/web/app/(authenticated)/(app)/app/keys/[keyId]/page.tsx index cc73a8ee80..f31438ccf9 100644 --- a/apps/web/app/(authenticated)/(app)/app/keys/[keyId]/page.tsx +++ b/apps/web/app/(authenticated)/(app)/app/keys/[keyId]/page.tsx @@ -45,7 +45,7 @@ export default async function KeyPage(props: { params: { keyId: string } }) { apiId: api.id, keyId: key.id, }), - getTotalUsage({ keyId: key.id }).then(res => res.data.at(0)?.totalUsage ?? 0), + getTotalUsage({ keyId: key.id }).then((res) => res.data.at(0)?.totalUsage ?? 0), getLatestVerifications({ keyId: key.id }), getLastUsed({ keyId: key.id }).then((res) => res.data.at(0)?.lastUsed ?? 0), ]); @@ -62,7 +62,7 @@ export default async function KeyPage(props: { params: { keyId: string } }) { y: value, })); - const fmt = new Intl.NumberFormat("en-US", { notation: "compact" }).format + const fmt = new Intl.NumberFormat("en-US", { notation: "compact" }).format; const usage30Days = usage.data.reduce((acc, { usage }) => acc + usage, 0); return (
@@ -73,7 +73,10 @@ export default async function KeyPage(props: { params: { keyId: string } }) { label="Expires" value={key.expires ? ms(key.expires.getTime() - Date.now()) : } /> - } /> + } + /> } diff --git a/apps/web/app/(authenticated)/(app)/app/keys/[keyId]/settings/delete-key.tsx b/apps/web/app/(authenticated)/(app)/app/keys/[keyId]/settings/delete-key.tsx index 23ab8eb1de..e71d4dfe64 100644 --- a/apps/web/app/(authenticated)/(app)/app/keys/[keyId]/settings/delete-key.tsx +++ b/apps/web/app/(authenticated)/(app)/app/keys/[keyId]/settings/delete-key.tsx @@ -1,7 +1,6 @@ "use client"; import { Button } from "@/components/ui/button"; import React, { useState } from "react"; -import { experimental_useFormStatus as useFormStatus } from "react-dom"; import { Card, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"; import { useToast } from "@/components/ui/use-toast";