Skip to content

fix: add Postgres-backed rate limiter for multi-worker deployments (#… #29

fix: add Postgres-backed rate limiter for multi-worker deployments (#…

fix: add Postgres-backed rate limiter for multi-worker deployments (#… #29

Workflow file for this run

name: propagate
on:
push:
branches: [main]
permissions:
contents: write
pull-requests: write
jobs:
propagate:
strategy:
fail-fast: false
matrix:
branch: [modal, hetzner]
runs-on: ubuntu-latest
steps:
- name: Generate token
id: create_token
uses: tibdex/github-app-token@v2
with:
app_id: ${{ secrets.APP_ID }}
private_key: ${{ secrets.PRIVATE_KEY }}
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ steps.create_token.outputs.token }}
- name: Install uv
uses: astral-sh/setup-uv@v4
- name: Attempt merge and push, or open PR on conflict
env:
GH_TOKEN: ${{ steps.create_token.outputs.token }}
BRANCH: ${{ matrix.branch }}
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
open_propagation_pr() {
TEMP_BRANCH="auto-merge/main-to-${BRANCH}-$(date +%Y%m%d%H%M%S)"
git checkout -b "$TEMP_BRANCH" origin/main
git push origin "$TEMP_BRANCH"
gh pr create \
--base "$BRANCH" \
--head "$TEMP_BRANCH" \
--title "Propagate main to ${BRANCH}" \
--body "$(cat <<'PREOF'
## Summary
- Auto-generated PR to propagate changes from `main` to the deployment branch
- Opened because an automatic merge had conflicts that need manual resolution
🤖 Generated by the propagate workflow
PREOF
)"
}
unresolved_conflicts() {
git diff --name-only --diff-filter=U | sort
}
conflicts_are_modal_overlay() {
[ "$BRANCH" = "modal" ] || return 1
conflicts="$(unresolved_conflicts)"
[ -n "$conflicts" ] || return 1
while IFS= read -r file; do
case "$file" in
pyproject.toml|uv.lock) ;;
*) return 1 ;;
esac
done <<< "$conflicts"
}
add_modal_dependency() {
python3 <<'PY'
from pathlib import Path
import subprocess
import tomllib
def is_modal_dependency(dependency: str) -> bool:
return dependency.split(";", 1)[0].strip().lower().startswith("modal")
def modal_dependency_from_branch() -> str:
try:
result = subprocess.run(
["git", "show", ":2:pyproject.toml"],
check=True,
capture_output=True,
text=True,
)
except subprocess.CalledProcessError:
return "modal>=0.73.162"
dependencies = tomllib.loads(result.stdout).get("project", {}).get("dependencies", [])
return next((dependency for dependency in dependencies if is_modal_dependency(dependency)), "modal>=0.73.162")
path = Path("pyproject.toml")
text = path.read_text()
data = tomllib.loads(text)
dependencies = data.get("project", {}).get("dependencies", [])
if any(is_modal_dependency(dependency) for dependency in dependencies):
raise SystemExit(0)
lines = text.splitlines()
start = next(
(index for index, line in enumerate(lines) if line.strip() == "dependencies = ["),
None,
)
if start is None:
raise SystemExit("Could not find project dependencies in pyproject.toml")
end = next(
(index for index in range(start + 1, len(lines)) if lines[index].strip() == "]"),
None,
)
if end is None:
raise SystemExit("Could not find end of project dependencies in pyproject.toml")
insert_at = end
for index in range(start + 1, end):
if lines[index].strip().startswith('"psycopg2-binary'):
insert_at = index
break
lines.insert(insert_at, f' "{modal_dependency_from_branch()}",')
path.write_text("\n".join(lines) + "\n")
PY
}
resolve_modal_overlay() {
if unresolved_conflicts | grep -qx "pyproject.toml"; then
git checkout --theirs pyproject.toml
fi
add_modal_dependency
if unresolved_conflicts | grep -qx "uv.lock"; then
git checkout --ours uv.lock
fi
uv lock
git add pyproject.toml uv.lock
remaining_conflicts="$(unresolved_conflicts)"
if [ -n "$remaining_conflicts" ]; then
echo "Conflicts remain after modal overlay resolution:"
echo "$remaining_conflicts"
return 1
fi
git commit --no-edit
git push origin "$BRANCH"
}
git checkout "$BRANCH"
if git merge origin/main --no-edit; then
echo "Merge succeeded, pushing to $BRANCH"
git push origin "$BRANCH"
elif conflicts_are_modal_overlay; then
echo "Merge conflict only affects the modal dependency overlay; resolving automatically"
resolve_modal_overlay
else
echo "Merge conflict detected, opening PR"
git merge --abort
open_propagation_pr
fi