Skip to content

Commit 31bf7bb

Browse files
authored
Merge branch 'develop' into web/task/display-name-validation
2 parents 65998b3 + 6aa57d9 commit 31bf7bb

193 files changed

Lines changed: 1836 additions & 1207 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/dependabot.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ updates:
3232
labels:
3333
- "mobile app"
3434
- "dependencies"
35+
groups:
36+
mobile-dependencies:
37+
patterns:
38+
- "*"
3539

3640
- package-ecosystem: "docker"
3741
directories:

.github/llm-bot/issue_bot.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
ALLOWED_LABELS = {
2525
"0.kind bug report",
2626
"0.kind feature request",
27+
"bug: login or signup",
2728
"bot-processed",
2829
}
2930

@@ -77,6 +78,36 @@
7778
# Structured Output Schema
7879
# ============================================================================
7980

81+
SIGNUP_LOGIN_SYSTEM_PROMPT = """You are a GitHub issue classifier for Couchers.org, a couch surfing platform.
82+
83+
Your job is to determine whether a GitHub issue is related to signup or login.
84+
85+
This includes issues about:
86+
- Creating a new account / signing up / registration
87+
- Logging in / authentication
88+
- Email verification during signup
89+
- Account activation
90+
- Unable to sign in or sign up
91+
- Session expiry / being logged out unexpectedly
92+
93+
If the issue is related to any of these topics, respond with is_signup_or_login = true.
94+
Otherwise, respond with is_signup_or_login = false.
95+
96+
Provide brief reasoning for your decision."""
97+
98+
99+
class SignupLoginDecision(BaseModel):
100+
"""Structured output for signup/login classification."""
101+
102+
reasoning: str = Field(
103+
description="Brief explanation of why this is or isn't related to signup/login"
104+
)
105+
106+
is_signup_or_login: bool = Field(
107+
description="Whether the issue is related to signup or login"
108+
)
109+
110+
80111
class IssueAction(str, Enum):
81112
"""Actions the bot can take on an issue."""
82113
CLOSE = "close"
@@ -137,6 +168,39 @@ def __init__(self):
137168
self.repo = self.github_client.get_repo(self.repo_name)
138169
self.issue = self.repo.get_issue(self.issue_number)
139170

171+
def check_signup_login(self) -> SignupLoginDecision:
172+
"""Use LLM to check if the issue is related to signup or login."""
173+
prompt = f"""{SIGNUP_LOGIN_SYSTEM_PROMPT}
174+
175+
Analyze this GitHub issue:
176+
177+
**Title:** {self.issue_title}
178+
179+
**Body:**
180+
{self.issue_body or "(empty)"}
181+
182+
Respond only in JSON with the following format:
183+
184+
```json
185+
{json.dumps(SignupLoginDecision.model_json_schema())}
186+
```
187+
"""
188+
189+
print(f"\nChecking if issue #{self.issue_number} is related to signup/login...")
190+
decision_dict = self.llm.json_complete(prompt, response_format=SignupLoginDecision)
191+
decision = SignupLoginDecision(**decision_dict)
192+
193+
print(f"Signup/Login: {decision.is_signup_or_login}")
194+
print(f"Reasoning: {decision.reasoning}")
195+
196+
return decision
197+
198+
def apply_signup_login_decision(self, decision: SignupLoginDecision):
199+
"""Apply the signup/login label if applicable."""
200+
if decision.is_signup_or_login:
201+
print(f"\nAdding 'bug: login or signup' label...")
202+
self.issue.add_to_labels("bug: login or signup")
203+
140204
def analyze_issue(self) -> BotDecision:
141205
"""Use LLM to analyze the issue and determine actions."""
142206
prompt = f"""{SYSTEM_PROMPT}
@@ -242,6 +306,9 @@ def apply_decision(self, decision: BotDecision):
242306
def run(self):
243307
"""Main execution flow."""
244308
try:
309+
signup_login_decision = self.check_signup_login()
310+
self.apply_signup_login_decision(signup_login_decision)
311+
245312
decision = self.analyze_issue()
246313
self.apply_decision(decision)
247314
except Exception as e:

.github/pull_request_template.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Fill applicable checklists below, or remove those that don't apply.
1919
- [ ] Added migrations if there are any database changes, rebased onto `develop` if necessary for linear migration history
2020

2121
**Web frontend checklist**
22-
<!-- To avoid CI failures, first run `yarn format` and `yarn lint --fix` in app/web, and run tests locally. -->
22+
<!-- To avoid CI failures, first run `yarn format` in app/web, and run tests locally. -->
2323
- [ ] There are no console warnings when running the app
2424
- [ ] Added tests where relevant
2525
- [ ] Clicked around my changes running locally and it works

.github/workflows/auto-format.yml

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ jobs:
1818
outputs:
1919
backend: ${{ steps.filter.outputs.backend }}
2020
frontend: ${{ steps.filter.outputs.frontend }}
21+
mobile: ${{ steps.filter.outputs.mobile }}
2122
models: ${{ steps.filter.outputs.models }}
2223
migrations: ${{ steps.filter.outputs.migrations }}
2324
templates: ${{ steps.filter.outputs.templates }}
@@ -32,6 +33,8 @@ jobs:
3233
- 'app/backend/**'
3334
frontend:
3435
- 'app/web/**'
36+
mobile:
37+
- 'app/mobile/**'
3538
models:
3639
- 'app/backend/src/couchers/models/**'
3740
migrations:
@@ -41,7 +44,7 @@ jobs:
4144
4245
format-backend:
4346
needs: detect-changes
44-
if: needs.detect-changes.outputs.backend == 'true'
47+
if: needs.detect-changes.outputs.backend == 'true' && github.actor != 'dependabot[bot]'
4548
runs-on: ubuntu-latest
4649
steps:
4750
- uses: actions/create-github-app-token@v2
@@ -82,7 +85,7 @@ jobs:
8285
8386
format-frontend:
8487
needs: detect-changes
85-
if: needs.detect-changes.outputs.frontend == 'true'
88+
if: needs.detect-changes.outputs.frontend == 'true' && github.actor != 'dependabot[bot]'
8689
runs-on: ubuntu-latest
8790
steps:
8891
- uses: actions/create-github-app-token@v2
@@ -125,9 +128,54 @@ jobs:
125128
git add app/web/
126129
git diff --staged --quiet || (git commit -m "Format frontend" && git push)
127130
131+
format-mobile:
132+
needs: detect-changes
133+
if: needs.detect-changes.outputs.mobile == 'true' && github.actor != 'dependabot[bot]'
134+
runs-on: ubuntu-latest
135+
steps:
136+
- uses: actions/create-github-app-token@v2
137+
id: app-token
138+
with:
139+
app-id: ${{ vars.APP_ID }}
140+
private-key: ${{ secrets.PRIVATE_KEY }}
141+
142+
- name: Get GitHub App User ID
143+
id: get-user-id
144+
run: echo "user-id=$(gh api "/users/${{ steps.app-token.outputs.app-slug }}[bot]" --jq .id)" >> "$GITHUB_OUTPUT"
145+
env:
146+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
147+
148+
- name: Configure git for GitHub App
149+
run: |
150+
git config --global user.name '${{ steps.app-token.outputs.app-slug }}[bot]'
151+
git config --global user.email '${{ steps.get-user-id.outputs.user-id }}+${{ steps.app-token.outputs.app-slug }}[bot]@users.noreply.github.com'
152+
153+
- uses: actions/checkout@v4
154+
with:
155+
ref: ${{ github.head_ref }}
156+
token: ${{ steps.app-token.outputs.token }}
157+
158+
- name: Setup Node.js
159+
uses: actions/setup-node@v4
160+
with:
161+
node-version: "22"
162+
163+
- name: Install dependencies
164+
working-directory: app/mobile
165+
run: npm ci
166+
167+
- name: Format mobile
168+
working-directory: app/mobile
169+
run: npm run format
170+
171+
- name: Commit and push mobile formatting changes
172+
run: |
173+
git add app/mobile/
174+
git diff --staged --quiet || (git commit -m "Format mobile" && git push)
175+
128176
generate-migration:
129177
needs: detect-changes
130-
if: needs.detect-changes.outputs.models == 'true' && needs.detect-changes.outputs.migrations == 'false'
178+
if: needs.detect-changes.outputs.models == 'true' && needs.detect-changes.outputs.migrations == 'false' && github.actor != 'dependabot[bot]'
131179
runs-on: ubuntu-latest
132180
services:
133181
postgres:
@@ -219,7 +267,7 @@ jobs:
219267
220268
regenerate-html-templates:
221269
needs: detect-changes
222-
if: needs.detect-changes.outputs.templates == 'true'
270+
if: needs.detect-changes.outputs.templates == 'true' && github.actor != 'dependabot[bot]'
223271
runs-on: ubuntu-latest
224272
steps:
225273
- uses: actions/create-github-app-token@v2

app/.gitlab-ci.yml

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ default:
5151
5252
# All jobs that use this must have full git history to correctly set the version number.
5353
if [ "$GIT_DEPTH" == "0" ]; then
54-
export DISPLAY_VERSION=$(base_ver=$(cat app/version); if [ "$CI_COMMIT_BRANCH" == "$RELEASE_BRANCH" ]; then echo "${base_ver}.$(git rev-list --count "origin/$RELEASE_BRANCH")"; else echo "${base_ver}-$SLUG"; fi)
54+
export COMMIT_NUMBER=$(git rev-list --count "origin/$RELEASE_BRANCH")
55+
export DISPLAY_VERSION=$(base_ver=$(cat app/version); if [ "$CI_COMMIT_BRANCH" == "$RELEASE_BRANCH" ]; then echo "${base_ver}.${COMMIT_NUMBER}"; else echo "${base_ver}-$SLUG"; fi)
5556
echo $DISPLAY_VERSION
5657
fi
5758
@@ -110,6 +111,21 @@ protos:
110111
paths:
111112
- app/
112113

114+
build:deploy-manifest:
115+
needs: ["protos"]
116+
stage: build
117+
variables:
118+
GIT_DEPTH: 0
119+
script:
120+
- sh app/deployment/build_manifest.sh app/backend/src/couchers/migrations/versions/ artifacts/deploy-info
121+
- mkdir -p artifacts/deploy-info/protos
122+
- cp app/proto/gen/descriptors.pb "artifacts/deploy-info/protos/${SLUG}.pb"
123+
artifacts:
124+
paths:
125+
- artifacts/deploy-info
126+
rules:
127+
- if: $CI_COMMIT_BRANCH == $RELEASE_BRANCH
128+
113129
build:proxy:
114130
needs: ["protos"]
115131
stage: build
@@ -560,6 +576,24 @@ test:mobile-typecheck:
560576
changes:
561577
- app/mobile/**/*
562578

579+
test:mobile-expo-doctor:
580+
needs: ["protos"]
581+
stage: test
582+
image: node:22
583+
inherit:
584+
default: false
585+
script:
586+
- cd app/mobile
587+
- npm ci
588+
- npm run build:protos
589+
- npx expo-doctor
590+
rules:
591+
- if: ($BUILD_MOBILE == "true") && ($DO_CHECKS == "true") && ($CI_COMMIT_BRANCH == $RELEASE_BRANCH)
592+
- if: ($BUILD_MOBILE == "true") && ($DO_CHECKS == "true") && ($CI_COMMIT_BRANCH != $RELEASE_BRANCH)
593+
changes:
594+
- app/mobile/package.json
595+
- app/mobile/package-lock.json
596+
563597
test:proxy:
564598
needs: ["build:proxy"]
565599
stage: test
@@ -827,6 +861,8 @@ wait:before-release:
827861
optional: true
828862
- job: build:nginx-next
829863
artifacts: false
864+
- job: build:deploy-manifest
865+
artifacts: false
830866
- job: test:backend
831867
artifacts: false
832868
optional: true
@@ -863,6 +899,9 @@ wait:before-release:
863899
- job: test:mobile-typecheck
864900
artifacts: false
865901
optional: true
902+
- job: test:mobile-expo-doctor
903+
artifacts: false
904+
optional: true
866905

867906
release:proxy:
868907
needs: ["wait:before-release"]
@@ -955,6 +994,18 @@ release:nginx-next:
955994
rules:
956995
- if: $CI_COMMIT_BRANCH == $RELEASE_BRANCH
957996

997+
release:deploy-info:
998+
needs: ["wait:before-release", "build:deploy-manifest"]
999+
stage: release
1000+
image: registry.gitlab.com/gitlab-org/cloud-deploy/aws-base:latest
1001+
inherit:
1002+
# no docker login
1003+
default: false
1004+
script:
1005+
- aws s3 cp artifacts/deploy-info/ "s3://$AWS_DEPLOY_BUCKET/" --recursive
1006+
rules:
1007+
- if: $CI_COMMIT_BRANCH == $RELEASE_BRANCH
1008+
9581009
deploy:staging:
9591010
needs: ["release:web-next", "release:backend"]
9601011
stage: deploy

app/backend/src/couchers/i18n/i18next.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from html import escape, unescape
99
from typing import Any
1010

11-
from babel import Locale
11+
from babel import Locale, UnknownLocaleError
1212
from markupsafe import Markup
1313

1414
PLURALIZABLE_VARIABLE_NAME = "count"
@@ -103,7 +103,11 @@ def find_string(self, key: str, substitutions: SubstitutionDict | None = None) -
103103
if substitutions:
104104
if count := substitutions.get(PLURALIZABLE_VARIABLE_NAME):
105105
if isinstance(count, int):
106-
plural_form = Locale(self.locale).plural_form(count)
106+
try:
107+
plural_form = Locale(self.locale).plural_form(count)
108+
except UnknownLocaleError:
109+
# Fallback to English-style plural rule.
110+
plural_form = "one" if 1 else "other"
107111
plural_key = key + "_" + plural_form
108112
if string := self.strings_by_key.get(plural_key):
109113
return string

app/backend/src/couchers/i18n/locales/pt-BR.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,14 @@
217217
"volunteer_not_found": "Voluntário não encontrado.",
218218
"wrong_signature": "Assinatura incorreta.",
219219
"wrong_sms_code": "O código está incorreto.",
220-
"signup_flow_motivations_filled": "Você já contou porque está se registrando."
220+
"signup_flow_motivations_filled": "Você já contou porque está se registrando.",
221+
"invalid_diagnostics_json": "JSON inválido em propriedades de evento de diagnóstico.",
222+
"admin_tag_already_exists": "Essa tag de administrador já existe.",
223+
"admin_tag_cant_be_empty": "A tag de administrador não pode estar vazia.",
224+
"admin_tag_not_found": "Tag de administrador não localizada.",
225+
"too_many_diagnostic_infos": "Muitos eventos de diagnóstico em um único lote.",
226+
"user_already_has_admin_tag": "O usuário já tem essa tag de administrador.",
227+
"user_does_not_have_admin_tag": "O usuário não tem essa tag de administrador."
221228
},
222229
"quick_links": {
223230
"do_not_email": "Você não receberá nenhum e-mail não relacionado a segurança, e seu status de hospedagem foi desabilitado. Você ainda pode receber a newsletter e precisa cancelar sua inscrição nela separadamente.",

app/backend/src/couchers/migrations/versions/0001_regenerate_all_migrations.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Regenerate all migrations
22
3-
Revision ID: 27a2782784d0
3+
Revision ID: 0001
44
Revises:
55
Create Date: 2021-04-02 14:56:26.236084
66
@@ -11,7 +11,7 @@
1111
from alembic import op
1212

1313
# revision identifiers, used by Alembic.
14-
revision = "27a2782784d0"
14+
revision = "0001"
1515
down_revision = None
1616
branch_labels = None
1717
depends_on = None

app/backend/src/couchers/migrations/versions/0002_add_filled_contributor_form_to_user.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Add filled_contributor_form to user
22
3-
Revision ID: 723394ace6b5
4-
Revises: 27a2782784d0
3+
Revision ID: 0002
4+
Revises: 0001
55
Create Date: 2021-04-11 11:48:11.170484
66
77
"""
@@ -10,8 +10,8 @@
1010
from alembic import op
1111

1212
# revision identifiers, used by Alembic.
13-
revision = "723394ace6b5"
14-
down_revision = "27a2782784d0"
13+
revision = "0002"
14+
down_revision = "0001"
1515
branch_labels = None
1616
depends_on = None
1717

0 commit comments

Comments
 (0)