Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
2faef15
v2.0.0-alpha.1 (#1146)
daveearley Jul 27, 2026
0a411d3
fix: disable HTMLPurifier definition cache in event locations migration
daveearley Jul 27, 2026
dee396f
v2 alpha UI fixes (#1283)
daveearley Jul 28, 2026
0dde449
Feature/v2 UI updates (#1284)
daveearley Jul 28, 2026
1318162
Feature: Ticket UI improvements (#1285)
daveearley Jul 28, 2026
1a39e7a
Fix deploy workflow and slim frontend SSR image (#1287)
daveearley Jul 28, 2026
bc94468
Feature: Announcement management (#1289)
daveearley Jul 29, 2026
f8dd05c
Feature: Make occurrence creation async (#1288)
daveearley Jul 30, 2026
3268c9f
Feature: Account Deletion Support (#1290)
daveearley Jul 30, 2026
f8b7261
Stripe disconnect, self-serve event currency change, and inline uploa…
daveearley Jul 30, 2026
e456bbf
Feature: Product add-ons, ticket creation redesign, and ticket select…
daveearley Aug 6, 2026
591674e
Occurrence modal refactor
daveearley Aug 7, 2026
8a5ae95
Feature: API doc generation (#1304)
daveearley Aug 8, 2026
39618a1
Merge branch 'develop' of github.com:HiEventsDev/hi.events into develop
daveearley Aug 8, 2026
d7da6a5
Feature: Make get tickets floating button configurable (#1305)
daveearley Aug 8, 2026
122d855
Merge branch 'develop' of github.com:HiEventsDev/hi.events into develop
daveearley Aug 8, 2026
819358b
Feature: Update event defaults (#1306)
daveearley Aug 9, 2026
76f587b
Fix: Bulk occurrence e2e (#1307)
daveearley Aug 9, 2026
45dde1d
Merge branch 'develop' of github.com:HiEventsDev/hi.events into develop
daveearley Aug 9, 2026
d5f9817
Chore: v2 i18n (#1308)
daveearley Aug 9, 2026
e2e5ab9
Chore: v2 i18n - 2 (#1309)
daveearley Aug 10, 2026
e5cb056
Merge branch 'develop' of github.com:HiEventsDev/hi.events into develop
daveearley Aug 10, 2026
68fecd4
Update README.md
daveearley Aug 10, 2026
b045fe7
Merge security fixes from main into develop (#1312)
daveearley Aug 11, 2026
51b095a
Feature: Checkout header redesign (#1310)
daveearley Aug 11, 2026
8d020d5
Reduce duplicate API requests across event management pages (#1314)
daveearley Aug 13, 2026
6fadf9b
Add k6 load test scripts (#1320)
daveearley Aug 23, 2026
d250ee5
Fix attendee questions, action bar overflow and dashboard stats UI (#…
daveearley Aug 23, 2026
5e8d2d3
Feature: Dashboard e2e tests (#1321)
daveearley Aug 23, 2026
cb307c1
Reduce frontend bundle size and bump @tanstack/react-query (#1322)
daveearley Aug 23, 2026
b06e498
Add refund support for offline payment orders (#1323)
daveearley Aug 24, 2026
1009928
Fix product preview bg color
daveearley Aug 24, 2026
ca0e983
Add notice to attendee message template
daveearley Aug 24, 2026
1546521
Merge branch 'develop' of github.com:HiEventsDev/hi.events into develop
daveearley Aug 24, 2026
fd3606a
V2 bug fixes
daveearley Aug 25, 2026
a2a0649
Feature: e2e fixes (#1324)
daveearley Aug 25, 2026
9d3722e
Fix migration + vapor timeout
daveearley Aug 26, 2026
048adec
Merge main into develop to resolve v2 release conflicts
daveearley Aug 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
64 changes: 64 additions & 0 deletions .agents/skills/translations/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
name: translations
description: Frontend translation workflow using Lingui - extracting, adding, and compiling translations for all supported languages
---

# Frontend Translation Workflow (Lingui)

IMPORTANT: Always update translations as you develop features. When adding new translatable strings, immediately add translations for all supported languages.

## Core Commands

```bash
cd frontend

# Extract translatable strings (use --clean for accurate counts)
yarn messages:extract --clean

# Compile translations for production
yarn messages:compile

# Check for untranslated strings
cd scripts && ./list_untranslated_strings.sh
```

## Process

1. **Extract**: `yarn messages:extract --clean`
2. **Check**: Look at the output table for missing translation counts
3. **Add translations**: Update the `.po` files for each language
4. **Verify**: Run extract again to confirm 0 missing
5. **Compile**: `yarn messages:compile`

## Adding Translations

Add entries to each locale's `.po` file in `frontend/src/locales/`:

```po
#: src/path/to/component.tsx:123
msgid "Your English String"
msgstr "Translated String"
```

## Supported Languages

| Code | Language |
|------|----------|
| en | English (source - no translation needed) |
| de | Deutsch |
| es | Espanol |
| fr | Francais |
| pt | Portugues |
| pt-br | Portugues do Brasil |
| it | Italiano |
| nl | Nederlands |
| zh-cn | Simplified Chinese |
| zh-hk | Traditional Chinese (HK) |
| vi | Tieng Viet |
| ru | Russian (currently untranslated) |

## Troubleshooting

- **Counts seem wrong**: Use `--clean` flag to remove obsolete entries
- **Translation not appearing**: Run `yarn messages:compile` after adding
- **Syntax errors**: Check for proper escaping of quotes in `.po` files
65 changes: 1 addition & 64 deletions .claude/skills/translations/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,64 +1 @@
---
name: translations
description: Frontend translation workflow using Lingui - extracting, adding, and compiling translations for all supported languages
---

# Frontend Translation Workflow (Lingui)

IMPORTANT: Always update translations as you develop features. When adding new translatable strings, immediately add translations for all supported languages.

## Core Commands

```bash
cd frontend

# Extract translatable strings (use --clean for accurate counts)
yarn messages:extract --clean

# Compile translations for production
yarn messages:compile

# Check for untranslated strings
cd scripts && ./list_untranslated_strings.sh
```

## Process

1. **Extract**: `yarn messages:extract --clean`
2. **Check**: Look at the output table for missing translation counts
3. **Add translations**: Update the `.po` files for each language
4. **Verify**: Run extract again to confirm 0 missing
5. **Compile**: `yarn messages:compile`

## Adding Translations

Add entries to each locale's `.po` file in `frontend/src/locales/`:

```po
#: src/path/to/component.tsx:123
msgid "Your English String"
msgstr "Translated String"
```

## Supported Languages

| Code | Language |
|------|----------|
| en | English (source - no translation needed) |
| de | Deutsch |
| es | Espanol |
| fr | Francais |
| pt | Portugues |
| pt-br | Portugues do Brasil |
| it | Italiano |
| nl | Nederlands |
| zh-cn | Simplified Chinese |
| zh-hk | Traditional Chinese (HK) |
| vi | Tieng Viet |
| ru | Russian (currently untranslated) |

## Troubleshooting

- **Counts seem wrong**: Use `--clean` flag to remove obsolete entries
- **Translation not appearing**: Run `yarn messages:compile` after adding
- **Syntax errors**: Check for proper escaping of quotes in `.po` files
see @../../../.agents/skills/translations/SKILL.md
12 changes: 12 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Revisions listed here are ignored by `git blame` (bulk reformatting, etc.).
#
# Enable locally with:
# git config blame.ignoreRevsFile .git-blame-ignore-revs
#
# GitHub applies this file automatically.

# style: apply Pint formatting across backend
b145fed4d0b0f82bf29f48145672f04bca6b5170

# style: remove explanatory comments across backend and frontend
00ba8bbb388d05e7d6498a25b049a47661d84861
45 changes: 35 additions & 10 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ on:
required: false
default: false
type: boolean
force_build:
description: 'Force a fresh DigitalOcean build (ignores the build cache)'
required: false
default: false
type: boolean

concurrency:
group: deploy-${{ github.event_name == 'workflow_dispatch' && github.event.inputs.environment || (github.ref_name == 'main' && 'production' || 'staging') }}
cancel-in-progress: false

jobs:
backend:
Expand All @@ -33,7 +42,7 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.3
php-version: 8.5
tools: composer:v2
coverage: none

Expand Down Expand Up @@ -135,11 +144,13 @@ jobs:
echo "DO_APP_ID=${{ secrets.DIGITALOCEAN_STAGING_APP_ID }}" >> "$GITHUB_ENV"
echo "TEST_MODE=false" >> "$GITHUB_ENV"
fi
echo "FORCE_BUILD=${{ github.event_name == 'workflow_dispatch' && github.event.inputs.force_build || 'false' }}" >> "$GITHUB_ENV"

- name: Log Environment Settings
run: |
echo "🚀 Deploying frontend to DigitalOcean App: ${{ env.DO_APP_ID }}"
echo "🧪 Test mode: ${{ env.TEST_MODE }}"
echo "🔨 Force build: ${{ env.FORCE_BUILD }}"

- name: Validate Deployment Configuration (Test Mode)
if: env.TEST_MODE == 'true'
Expand All @@ -154,7 +165,8 @@ jobs:
run: |
RESPONSE=$(curl -s -o response.json -w "%{http_code}" -X POST "https://api.digitalocean.com/v2/apps/$DO_APP_ID/deployments" \
-H "Authorization: Bearer ${{ secrets.DIGITALOCEAN_API_TOKEN }}" \
-H "Content-Type: application/json")
-H "Content-Type: application/json" \
-d "{\"force_build\": $FORCE_BUILD}")

if [ "$RESPONSE" -ne 201 ] && [ "$RESPONSE" -ne 200 ]; then
ERROR_MSG=$(jq -r '.message // "Unknown error occurred."' response.json)
Expand All @@ -176,7 +188,7 @@ jobs:
- name: Poll Deployment Status
if: env.TEST_MODE != 'true'
run: |
MAX_RETRIES=60
MAX_RETRIES=90
SLEEP_TIME=10
COUNTER=0

Expand All @@ -185,18 +197,31 @@ jobs:
-H "Authorization: Bearer ${{ secrets.DIGITALOCEAN_API_TOKEN }}" \
-H "Content-Type: application/json")

STATUS=$(echo "$RESPONSE" | jq -r '.deployment.phase')
STATUS=$(echo "$RESPONSE" | jq -r '.deployment.phase // "UNKNOWN"')

echo "🔄 Deployment Status: $STATUS"

if [ "$STATUS" == "ACTIVE" ]; then
echo "✅ Deployment completed successfully."
exit 0
elif [[ "$STATUS" == "FAILED" || "$STATUS" == "CANCELED" ]]; then
echo "❌ Deployment failed or was cancelled."
exit 1
if [ -z "${DEPLOYMENT_LOGGED:-}" ] && [ "$STATUS" != "UNKNOWN" ]; then
echo "📦 $(echo "$RESPONSE" | jq -r '.deployment | "cause=\(.cause // "unknown") build_reused_from=\(.cloned_from // "none")"')"
echo "🔖 $(echo "$RESPONSE" | jq -r '[.deployment | ((.services//[]) + (.workers//[]) + (.jobs//[]) + (.static_sites//[])) | .[] | "\(.name)@\(.source_commit_hash[0:7] // "?")"] | join(" ") | if . == "" then "(no components reported)" else . end')"
DEPLOYMENT_LOGGED=1
fi

case "$STATUS" in
ACTIVE)
echo "✅ Deployment completed successfully."
exit 0
;;
SUPERSEDED)
echo "⏭️ Superseded by a newer deployment, which is now responsible for this app."
exit 0
;;
ERROR|CANCELED)
echo "❌ Deployment finished in state: $STATUS"
exit 1
;;
esac

COUNTER=$((COUNTER + 1))
echo "⏳ Retrying in $SLEEP_TIME seconds... ($COUNTER/$MAX_RETRIES)"
sleep $SLEEP_TIME
Expand Down
158 changes: 158 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
name: E2E Tests

on:
push:
branches: [main, develop]
paths:
- 'backend/**'
- 'frontend/**'
- 'e2e/**'
- 'docker/e2e/**'
- '.github/workflows/e2e.yml'
pull_request:
types: [opened, synchronize, reopened, labeled]
paths:
- 'backend/**'
- 'frontend/**'
- 'e2e/**'
- 'docker/e2e/**'
- '.github/workflows/e2e.yml'
schedule:
- cron: '0 3 * * *'

concurrency:
group: e2e-${{ github.ref }}
cancel-in-progress: true

jobs:
plan:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set.outputs.matrix }}
steps:
- id: set
env:
FULL: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'full-e2e') }}
run: |
if [ "$FULL" = "true" ]; then
echo 'matrix={"include":[{"name":"full-1","pw_args":"--shard=1/2"},{"name":"full-2","pw_args":"--shard=2/2"}]}' >> "$GITHUB_OUTPUT"
else
echo 'matrix={"include":[{"name":"smoke","pw_args":"--grep @smoke"}]}' >> "$GITHUB_OUTPUT"
fi

e2e:
needs: plan
runs-on: ubuntu-latest
timeout-minutes: 30

permissions:
contents: read
pull-requests: write

strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.plan.outputs.matrix) }}

env:
COMPOSE_FILE: docker/e2e/docker-compose.e2e.yml
E2E_IMAGE_TAG: ci
STRIPE_PUBLIC_KEY: ${{ secrets.STRIPE_TEST_PUBLIC_KEY }}
STRIPE_SECRET_KEY: ${{ secrets.STRIPE_TEST_SECRET_KEY }}

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

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build backend image
uses: docker/build-push-action@v6
with:
context: ./backend
file: ./backend/Dockerfile
load: true
tags: hievents-e2e-backend:ci
cache-from: type=gha,scope=e2e-backend
cache-to: type=gha,scope=e2e-backend,mode=max

- name: Build frontend image
uses: docker/build-push-action@v6
with:
context: ./frontend
file: ./frontend/Dockerfile.ssr
load: true
tags: hievents-e2e-frontend:ci
cache-from: type=gha,scope=e2e-frontend
cache-to: type=gha,scope=e2e-frontend,mode=max

- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
cache-dependency-path: e2e/package-lock.json

- name: Cache Playwright browsers
uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ hashFiles('e2e/package-lock.json') }}

- name: Run E2E suite
run: ./e2e/run-e2e.sh -- ${{ matrix.pw_args }}

- name: Write job summary
if: ${{ !cancelled() }}
env:
SHARD_NAME: ${{ matrix.name }}
run: node e2e/scripts/github-summary.mjs e2e/test-results/results.json | tee e2e-summary.md >> "$GITHUB_STEP_SUMMARY"

- name: Comment summary on PR
if: ${{ !cancelled() && github.event_name == 'pull_request' }}
uses: actions/github-script@v7
env:
SHARD_NAME: ${{ matrix.name }}
with:
script: |
const fs = require('fs');
const marker = `<!-- e2e-summary-${process.env.SHARD_NAME} -->`;
const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
const summary = fs.existsSync('e2e-summary.md')
? fs.readFileSync('e2e-summary.md', 'utf8')
: '⚠️ No summary was generated — check the "Write job summary" step logs.';
const body = `${marker}\n${summary}\n\n[View run](${runUrl})`.slice(0, 65000);
try {
const comments = await github.paginate(github.rest.issues.listComments, {
...context.repo,
issue_number: context.issue.number,
per_page: 100,
});
const existing = comments.find((c) => c.body?.includes(marker));
if (existing) {
await github.rest.issues.updateComment({ ...context.repo, comment_id: existing.id, body });
} else {
await github.rest.issues.createComment({ ...context.repo, issue_number: context.issue.number, body });
}
} catch (error) {
core.warning(`Could not post PR comment (fork PRs have a read-only token): ${error.message}`);
}

- name: Collect stack logs on failure
if: failure()
run: docker compose -f "$COMPOSE_FILE" logs --no-color > e2e/compose-logs.txt

- name: Upload report and artifacts
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: playwright-report-${{ matrix.name }}
path: |
e2e/playwright-report/
e2e/test-results/
e2e/compose-logs.txt
retention-days: 14

- name: Tear down the stack
if: always()
run: docker compose -f "$COMPOSE_FILE" down -v
Loading
Loading