Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
33 changes: 28 additions & 5 deletions .github/Pull_Request_Template.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,30 @@
## κ°œμš”
>
πŸ’‘ μž‘μ—… μš”μ•½
<!-- λ³Έ PRμ—μ„œ μž‘μ—…ν•œ λ‚΄μš©μ„ κ°„λž΅ν•˜κ²Œ μ„€λͺ…ν•΄μ£Όμ„Έμš”. -->

## μž‘μ—…μ‚¬ν•­
-
πŸ”— κ΄€λ ¨ 이슈
<!-- λ³Έ PRκ³Ό κ΄€λ ¨λœ 이슈 번호λ₯Ό μž‘μ„±ν•΄μ£Όμ„Έμš”. (예: Closes #123) -->
Closes #

## μΆ”κ°€ 둜 ν•  말
πŸ› οΈ μž‘μ—… λ‚΄μ—­
<!-- λ³Έ PRμ—μ„œ λ³€κ²½λœ μ‚¬ν•­μ΄λ‚˜ μƒˆλ‘­κ²Œ μΆ”κ°€λœ κΈ°λŠ₯을 ꡬ체적으둜 μ μ–΄μ£Όμ„Έμš”. -->
- [ ]
- [ ]

πŸ“Έ μŠ€ν¬λ¦°μƒ· / GIF (선택)
<!-- UI λ³€κ²½ 사항이 μžˆλ‹€λ©΄ μŠ€ν¬λ¦°μƒ·μ΄λ‚˜ ν™”λ©΄ λ…Ήν™”(GIF)λ₯Ό μ²¨λΆ€ν•΄μ£Όμ„Έμš”. -->
| AS-IS (λ³€κ²½ μ „) | TO-BE (λ³€κ²½ ν›„) |
| :---: | :---: |
| <!-- 이미지 첨뢀 --> | <!-- 이미지 첨뢀 --> |

πŸ§ͺ ν…ŒμŠ€νŠΈ 방법
<!-- 리뷰어가 이 PR의 λ³€κ²½ 사항을 μ–΄λ–»κ²Œ ν…ŒμŠ€νŠΈν•΄ λ³Ό 수 μžˆλŠ”μ§€ μ„€λͺ…ν•΄μ£Όμ„Έμš”. -->
- [ ] (예: νŠΉμ • ν™”λ©΄ μ§„μž… ν›„ λ²„νŠΌ 클릭)

⚠️ λ¦¬λ·°μ–΄μ—κ²Œ ν•  말 (선택)
<!-- 리뷰어가 μ€‘μ μ μœΌλ‘œ 봐야 ν•  λΆ€λΆ„μ΄λ‚˜, μΆ”κ°€λ‘œ 남기고 싢은 μ½”λ©˜νŠΈκ°€ μžˆλ‹€λ©΄ μž‘μ„±ν•΄μ£Όμ„Έμš”. -->

βœ… 체크리슀트
- [ ] μ½”λ“œλ₯Ό 슀슀둜 λ¦¬λ·°ν•˜κ³  μˆ˜μ •ν–ˆλ‚˜μš”?
- [ ] Android Studioμ—μ„œ λΉŒλ“œκ°€ μ •μƒμ μœΌλ‘œ μ™„λ£Œλ˜λ‚˜μš”?
- [ ] μ΄ν•΄ν•˜κΈ° μ–΄λ €μš΄ μ½”λ“œμ— 주석을 λ‹¬μ•˜λ‚˜μš”?
- [ ] μ»¨λ²€μ…˜μ— 맞게 μ½”λ“œλ₯Ό μž‘μ„±ν–ˆλ‚˜μš”?
43 changes: 43 additions & 0 deletions .github/workflows/DeployFunctions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Deploy Functions

on:
push:
branches: [develop]
paths:
- 'functions/**'
- '.github/workflows/DeployFunctions.yml'
workflow_dispatch:

concurrency:
group: deploy-functions-${{ github.ref }}
cancel-in-progress: false

jobs:
deploy:
name: Deploy Firebase Functions
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '22'

- name: Install dependencies
run: npm install
working-directory: functions

- name: Build
run: npm run build
working-directory: functions

- name: Deploy Firebase Functions
run: |
npm install -g firebase-tools
firebase deploy --only functions --project team-dms
working-directory: functions
env:
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
72 changes: 72 additions & 0 deletions .github/workflows/DeployRunner.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: Deploy Runner

on:
push:
branches: [develop]
paths:
- 'services/auto-fix-runner/**'
- '.github/workflows/DeployRunner.yml'
workflow_dispatch:

concurrency:
group: deploy-runner-${{ github.ref }}
cancel-in-progress: false

env:
PROJECT_ID: team-dms
REGION: us-central1
SERVICE_NAME: auto-fix-runner
IMAGE: us-central1-docker.pkg.dev/team-dms/auto-fix-runner/runner

jobs:
deploy:
name: Build & Deploy to Cloud Run
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ secrets.GCP_RUNNER_SERVICE_ACCOUNT }}

- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@v2

- name: Configure Docker for Artifact Registry
run: gcloud auth configure-docker us-central1-docker.pkg.dev --quiet

- name: Build Docker image
run: |
docker build \
-t ${{ env.IMAGE }}:${{ github.sha }} \
-t ${{ env.IMAGE }}:latest \
services/auto-fix-runner/

- name: Push Docker image
run: |
docker push ${{ env.IMAGE }}:${{ github.sha }}
docker push ${{ env.IMAGE }}:latest

- name: Deploy to Cloud Run
run: |
gcloud run deploy ${{ env.SERVICE_NAME }} \
--image "${{ env.IMAGE }}:${{ github.sha }}" \
--region ${{ env.REGION }} \
--platform managed \
--allow-unauthenticated \
--set-secrets \
"RUNNER_SHARED_TOKEN=RUNNER_SHARED_TOKEN:latest,GITHUB_APP_ID=GITHUB_APP_ID:latest,GITHUB_INSTALLATION_ID=GITHUB_INSTALLATION_ID:latest,GITHUB_APP_PRIVATE_KEY=GITHUB_APP_PRIVATE_KEY:latest" \
--quiet
Comment on lines +57 to +66

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, locate and read the cross-file context mentioned
cat -n functions/src/index.ts | sed -n '1243,1250p'

Repository: team-aliens/DMS-Android

Length of output: 376


🏁 Script executed:

# Get more context around those lines to understand the caller
cat -n functions/src/index.ts | sed -n '1230,1260p'

Repository: team-aliens/DMS-Android

Length of output: 1122


🏁 Script executed:

# Search for all invocations of the Cloud Run runner service
rg -i "cloud.*run|runner.*service|SERVICE_NAME" --type js --type ts -A 3 -B 3

Repository: team-aliens/DMS-Android

Length of output: 466


🏁 Script executed:

# Check if there are other workflows or code that might invoke this service
git ls-files | grep -E '\.(yml|yaml|ts|js)$' | head -20

Repository: team-aliens/DMS-Android

Length of output: 430


🏁 Script executed:

# Search for all calls to callAgentRunner function
rg "callAgentRunner" --type ts --type js -B 5 -A 2

Repository: team-aliens/DMS-Android

Length of output: 887


🏁 Script executed:

# Search for references to AUTO_FIX_RUNNER_URL and AUTO_FIX_RUNNER_TOKEN
rg "AUTO_FIX_RUNNER_(URL|TOKEN)" --type ts --type js -B 2 -A 2

Repository: team-aliens/DMS-Android

Length of output: 1208


🏁 Script executed:

# Check the runner service implementation
cat -n services/auto-fix-runner/index.js | head -100

Repository: team-aliens/DMS-Android

Length of output: 3159


🏁 Script executed:

# Look for Cloud Functions entry points to understand if this is truly backend-only
rg "exports\." functions/src/index.ts --type ts -B 2 -A 5 | head -50

Repository: team-aliens/DMS-Android

Length of output: 49


🏁 Script executed:

# Find all HTTP function exports to understand which endpoints are public
rg "exports\.\w+" functions/src/index.ts --type ts -A 3 | head -80

Repository: team-aliens/DMS-Android

Length of output: 49


🏁 Script executed:

# Search for where callAgentRunner is invoked - find the caller
rg "callAgentRunner\(" functions/src/index.ts --type ts -B 20 | head -60

Repository: team-aliens/DMS-Android

Length of output: 1313


🏁 Script executed:

# Check if the runner service validates the bearer token
rg "Bearer|authorization|RUNNER_SHARED_TOKEN" services/auto-fix-runner/index.js --type js -B 3 -A 3

Repository: team-aliens/DMS-Android

Length of output: 845


🏁 Script executed:

# Look for authentication middleware in the runner service
cat -n services/auto-fix-runner/index.js | sed -n '1,200p'

Repository: team-aliens/DMS-Android

Length of output: 6734


🏁 Script executed:

# Search for function definitions and HTTP handlers more broadly
rg "^\s*(export\s+)?(async\s+)?function|app\.(post|get|put|delete)|exports\s*=" functions/src/index.ts --type ts -A 2 | head -100

Repository: team-aliens/DMS-Android

Length of output: 3159


🏁 Script executed:

# Look at the end of the functions file to see what's exported
tail -100 functions/src/index.ts

Repository: team-aliens/DMS-Android

Length of output: 2774


🏁 Script executed:

# Search for onRequest or similar Cloud Functions HTTP trigger patterns
rg "onRequest|onCall|https\(" functions/src/index.ts --type ts -B 3 -A 5

Repository: team-aliens/DMS-Android

Length of output: 669


Prefer IAM-authenticated service-to-service invocation for the Cloud Run runner.

The runner handles sensitive GitHub operations (branch creation, commits, PRs) and is deployed with --allow-unauthenticated. While the runner validates a shared bearer token at the application level, this approach is weaker than IAM-based authentication. Since the runner is only invoked from backend code (Cloud Functions triggered via Slack interactions), restrict it to authenticated calls only using Cloud Run's IAM instead of relying on an environment variable secret.

πŸ€– Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/DeployRunner.yml around lines 57 - 66, Remove the
--allow-unauthenticated flag from the gcloud run deploy step and instead
configure IAM-based invoker access for the deployed service: keep the existing
deploy command (including --set-secrets and image/region args) but omit
--allow-unauthenticated, and add a post-deploy step that runs gcloud run
services add-iam-policy-binding for the deployed service (use the SERVICE_NAME /
env.SERVICE_NAME and grant roles/run.invoker to the calling backend service
account, e.g., the Cloud Functions serviceAccount) so only authenticated
service-to-service calls can invoke the Cloud Run runner.


- name: Print service URL
run: |
gcloud run services describe ${{ env.SERVICE_NAME }} \
--region ${{ env.REGION }} \
--format "value(status.url)"
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -196,3 +196,7 @@ app/release/

.claude/
.gemini/
.omx/

functions/.env
functions/.env.*
20 changes: 20 additions & 0 deletions firebase.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"functions": [
{
"source": "functions",
"codebase": "default",
"disallowLegacyRuntimeConfig": true,
"ignore": [
"node_modules",
".git",
"firebase-debug.log",
"firebase-debug.*.log",
"*.local"
],
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
]
}
]
}
33 changes: 33 additions & 0 deletions functions/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module.exports = {
root: true,
env: {
es6: true,
node: true,
},
extends: [
"eslint:recommended",
"plugin:import/errors",
"plugin:import/warnings",
"plugin:import/typescript",
"google",
"plugin:@typescript-eslint/recommended",
],
parser: "@typescript-eslint/parser",
parserOptions: {
project: ["tsconfig.json", "tsconfig.dev.json"],
sourceType: "module",
},
ignorePatterns: [
"/lib/**/*", // Ignore built files.
"/generated/**/*", // Ignore generated files.
],
plugins: [
"@typescript-eslint",
"import",
],
rules: {
"quotes": ["error", "double"],
"import/no-unresolved": 0,
"indent": ["error", 2],
},
};
12 changes: 12 additions & 0 deletions functions/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Compiled JavaScript files
lib/**/*.js
lib/**/*.js.map

# TypeScript v1 declaration files
typings/

# Node.js dependency directory
node_modules/
*.local
.env
.env.*
Loading