diff --git a/.github/workflows/build-hk-low-vol-snapshot-artifacts.yml b/.github/workflows/build-hk-low-vol-snapshot-artifacts.yml index 59a46f3..8e27aa4 100644 --- a/.github/workflows/build-hk-low-vol-snapshot-artifacts.yml +++ b/.github/workflows/build-hk-low-vol-snapshot-artifacts.yml @@ -121,6 +121,7 @@ jobs: build: name: Build HK snapshot artifacts runs-on: ubuntu-latest + timeout-minutes: 60 permissions: contents: read id-token: write diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3155102..102ede8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,9 +5,13 @@ on: branches: [ main ] pull_request: +permissions: + contents: read + jobs: test: runs-on: ubuntu-latest + timeout-minutes: 20 steps: - name: Checkout uses: actions/checkout@v6 @@ -49,7 +53,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v6 with: - python-version: "3.11" + python-version: "3.12" - name: Install dependencies run: | diff --git a/.github/workflows/dependabot_auto_merge.yml b/.github/workflows/dependabot_auto_merge.yml index f3f9f1a..a3a4988 100644 --- a/.github/workflows/dependabot_auto_merge.yml +++ b/.github/workflows/dependabot_auto_merge.yml @@ -9,6 +9,7 @@ jobs: auto-merge: if: github.event.workflow_run.conclusion == 'success' && startsWith(github.event.workflow_run.head_branch, 'dependabot/') runs-on: ubuntu-latest + timeout-minutes: 10 permissions: contents: write pull-requests: write diff --git a/.github/workflows/execution-report-heartbeat.yml b/.github/workflows/execution-report-heartbeat.yml index 6bab5ea..731f4e8 100644 --- a/.github/workflows/execution-report-heartbeat.yml +++ b/.github/workflows/execution-report-heartbeat.yml @@ -24,10 +24,15 @@ env: GCP_WORKLOAD_IDENTITY_PROVIDER: projects/252919773759/locations/global/workloadIdentityPools/github-actions/providers/github-main GCP_WORKLOAD_IDENTITY_SERVICE_ACCOUNT: longbridge-platform-deploy@longbridgequant.iam.gserviceaccount.com +concurrency: + group: ${{ github.workflow }}-${{ github.ref_name }} + cancel-in-progress: false + jobs: heartbeat: name: Check ${{ matrix.target.label }} execution report heartbeat runs-on: ubuntu-latest + timeout-minutes: 15 strategy: fail-fast: false matrix: diff --git a/.github/workflows/invoke-cloud-run.yml b/.github/workflows/invoke-cloud-run.yml index ac88ea7..8c52d3f 100644 --- a/.github/workflows/invoke-cloud-run.yml +++ b/.github/workflows/invoke-cloud-run.yml @@ -23,10 +23,15 @@ env: GCP_WORKLOAD_IDENTITY_PROVIDER: projects/252919773759/locations/global/workloadIdentityPools/github-actions/providers/github-main GCP_WORKLOAD_IDENTITY_SERVICE_ACCOUNT: longbridge-platform-deploy@longbridgequant.iam.gserviceaccount.com +concurrency: + group: ${{ github.workflow }}-${{ github.ref_name }} + cancel-in-progress: false + jobs: invoke: name: Invoke ${{ inputs.environment }} Cloud Run runs-on: ubuntu-latest + timeout-minutes: 15 permissions: contents: read id-token: write diff --git a/.github/workflows/runtime-guard.yml b/.github/workflows/runtime-guard.yml index 833bd2d..9f18777 100644 --- a/.github/workflows/runtime-guard.yml +++ b/.github/workflows/runtime-guard.yml @@ -32,10 +32,15 @@ env: GCP_WORKLOAD_IDENTITY_PROVIDER: projects/252919773759/locations/global/workloadIdentityPools/github-actions/providers/github-main GCP_WORKLOAD_IDENTITY_SERVICE_ACCOUNT: longbridge-platform-deploy@longbridgequant.iam.gserviceaccount.com +concurrency: + group: ${{ github.workflow }}-${{ github.ref_name }} + cancel-in-progress: false + jobs: guard: name: Check ${{ matrix.target.label }} Cloud Run runtime runs-on: ubuntu-latest + timeout-minutes: 15 strategy: fail-fast: false matrix: diff --git a/.github/workflows/sync-cloud-run-env.yml b/.github/workflows/sync-cloud-run-env.yml index 4352b7b..0c47773 100644 --- a/.github/workflows/sync-cloud-run-env.yml +++ b/.github/workflows/sync-cloud-run-env.yml @@ -55,10 +55,15 @@ env: GCP_RUNTIME_SERVICE_ACCOUNT: longbridge-platform-runtime@longbridgequant.iam.gserviceaccount.com GCP_ARTIFACT_REGISTRY_REPOSITORY: cloud-run-source-deploy +concurrency: + group: ${{ github.workflow }}-${{ github.ref_name }} + cancel-in-progress: false + jobs: sync: name: Deploy / Sync ${{ matrix.target.label }} Cloud Run runs-on: ubuntu-latest + timeout-minutes: 20 strategy: fail-fast: false matrix: diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..e4fba21 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.12 diff --git a/tests/test_request_handling.py b/tests/test_request_handling.py index d1bc975..0f200a4 100644 --- a/tests/test_request_handling.py +++ b/tests/test_request_handling.py @@ -200,6 +200,23 @@ def load_module(): class RequestHandlingTests(unittest.TestCase): + def test_cloud_run_route_contracts_are_registered(self): + module = load_module() + + self.assertIs(module.app._routes[("/", ("POST", "GET"))], module.handle_trigger) + self.assertIs( + module.app._routes[("/backfill", ("POST", "GET"))], + module.handle_backfill, + ) + self.assertIs( + module.app._routes[("/precheck", ("POST", "GET"))], + module.handle_precheck, + ) + self.assertIs( + module.app._routes[("/probe", ("POST", "GET"))], + module.handle_probe, + ) + def test_handle_trigger_runs_strategy(self): module = load_module() observed = {"called": False}