Support multiple GTFS-RT feeds#130
Conversation
📝 WalkthroughWalkthroughThis PR adds GTFS_RT_FEEDS (a JSON array) and prefers it in bootstrap, normalizes legacy single-feed env vars into a FEEDS array, updates the Handlebars template to render one GtfsRealtimeSource per feed, adds Go renderer tests, CI coverage, deployment examples, and design/planning docs. ChangesMulti-Feed GTFS-RT Configuration Support
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/test.yaml:
- Around line 10-12: jobs.renderer currently lacks a job-level permissions block
and uses unchecked checkout and tag-pinned actions; add a minimal permissions
section (e.g., permissions: contents: read) to jobs.renderer, change the
actions/checkout step to set persist-credentials: false, and replace tag-only
references (actions/checkout@v4, actions/setup-go@v5) with pinned commit SHAs or
otherwise pin the action versions to specific commits to avoid floating tags.
- Around line 14-19: Replace tag-based GitHub Actions and enable non-persistent
checkout: change uses: actions/checkout@v4 and uses: actions/setup-go@v5 to
pinned commit SHAs for those actions, and add persist-credentials: false to the
checkout step (the actions/checkout usage) to disable credential persistence;
apply the same changes to the other workflow referenced (the actions/checkout
step in the docker workflow). Ensure you update the specific occurrences of
"actions/checkout" and "actions/setup-go" in the workflows so they reference
commit SHAs rather than version tags and add the persist-credentials: false
field to each checkout step.
In `@oba/bootstrap.sh`:
- Around line 40-43: The precedence bug comes from treating
GTFS_RT_FEEDS_TRIMMED == "[]" as unset so legacy vars can override it; change
the logic to first detect whether GTFS_RT_FEEDS_TRIMMED is set at all (use a
"variable is set" test) and, if set, always assign FEEDS_JSON="$GTFS_RT_FEEDS"
(so explicit "[]" is preserved), otherwise fall back to the legacy
TRIP_UPDATES_URL / VEHICLE_POSITIONS_URL branch; update the conditional around
GTFS_RT_FEEDS_TRIMMED and the assignment to FEEDS_JSON (references:
GTFS_RT_FEEDS_TRIMMED and FEEDS_JSON) accordingly so explicit empty lists take
precedence.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 7e38627d-0074-474b-8311-07d459541a50
📒 Files selected for processing (5)
.github/workflows/test.yamlREADME.mdoba/bootstrap.shoba/config/onebusaway-transit-data-federation-webapp-data-sources.xml.hbsoba/config/template_renderer/main_test.go
| - name: Checkout code | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Set up Go | ||
| uses: actions/setup-go@v5 | ||
| with: |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find unpinned uses (not @<40-hex-sha>) and checkout steps missing persist-credentials.
rg -n --iglob '.github/workflows/*.y*ml' 'uses:\s*[^[:space:]]+@([^[:space:]]+)$'
rg -n --iglob '.github/workflows/*.y*ml' 'uses:\s*actions/checkout@'
rg -n --iglob '.github/workflows/*.y*ml' 'persist-credentials:\s*false'Repository: OneBusAway/docker
Length of output: 508
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== Workflow files =="
ls -la .github/workflows || true
fd -e yml -e yaml .github/workflows -a || true
echo
echo "== test.yaml (relevant section) =="
if [ -f .github/workflows/test.yaml ]; then
nl -ba .github/workflows/test.yaml | sed -n '1,120p'
else
echo "MISSING: .github/workflows/test.yaml"
# Try to find similarly named file(s)
fd -a "test.*y*ml" .github/workflows || true
fi
echo
echo "== Search for checkout/setup-go/persist-credentials =="
# Use a broad search path that will actually match existing files
rg -n --hidden --glob '.github/workflows/*.{yml,yaml}' \
'uses:\s*actions/(checkout|setup-go)@' .github/workflows || true
rg -n --hidden --glob '.github/workflows/*.{yml,yaml}' \
'persist-credentials:\s*false' .github/workflows || true
rg -n --hidden --glob '.github/workflows/*.{yml,yaml}' \
'uses:\s*[^[:space:]]+@v[0-9]+' .github/workflows || trueRepository: OneBusAway/docker
Length of output: 785
🏁 Script executed:
#!/bin/bash
# If .github/workflows doesn't exist, list repository top-level quickly (non-destructive)
ls -la .github || true
ls -la . || trueRepository: OneBusAway/docker
Length of output: 1680
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== test.yaml lines 1-80 =="
sed -n '1,80p' .github/workflows/test.yaml | nl -ba 2>/dev/null || sed -n '1,80p' .github/workflows/test.yaml
echo
echo "== test.yaml lines 10-40 (focus) =="
sed -n '10,40p' .github/workflows/test.yaml
echo
echo "== docker.yaml lines 1-120 =="
sed -n '1,120p' .github/workflows/docker.yaml
echo
echo "== rg: actions/checkout and persist-credentials =="
rg -n '.github/workflows/.*' --no-heading 'uses:\s*actions/checkout@' .github/workflows/*.yml .github/workflows/*.yaml 2>/dev/null || true
rg -n 'persist-credentials:\s*false' .github/workflows/*.yml .github/workflows/*.yaml 2>/dev/null || true
echo
echo "== rg: actions/setup-go =="
rg -n 'uses:\s*actions/setup-go@' .github/workflows/*.yml .github/workflows/*.yaml 2>/dev/null || true
echo
echo "== rg: any uses pinned to full commit SHAs? (40 hex) =="
rg -n 'uses:\s*(actions/checkout|actions/setup-go)@[0-9a-f]{40}' .github/workflows/*.yml .github/workflows/*.yaml 2>/dev/null || trueRepository: OneBusAway/docker
Length of output: 6470
🏁 Script executed:
#!/bin/bash
# fallback: print with awk line numbers if nl missing
awk 'NR>=1 && NR<=80 {printf "%5d %s\n", NR, $0}' .github/workflows/test.yaml | head -n 90Repository: OneBusAway/docker
Length of output: 2283
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== Any persist-credentials settings in workflows =="
rg -n 'persist-credentials:' .github/workflows/*.yml .github/workflows/*.yaml || true
echo
echo "== All actions/checkout@ usages (with nearby context) =="
rg -n --context 2 'uses:\s*actions/checkout@' .github/workflows/*.yml .github/workflows/*.yaml
echo
echo "== All actions/setup-go@ usages (with nearby context) =="
rg -n --context 2 'uses:\s*actions/setup-go@' .github/workflows/*.yml .github/workflows/*.yamlRepository: OneBusAway/docker
Length of output: 2082
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== workflow yaml files =="
ls -la .github/workflows
echo
echo "== persist-credentials settings (yaml only) =="
rg -n 'persist-credentials:' .github/workflows/*.yaml || true
echo
echo "== actions/checkout@ usages (yaml only) =="
rg -n 'uses:\s*actions/checkout@' .github/workflows/*.yaml
echo
echo "== actions/setup-go@ usages (yaml only) =="
rg -n 'uses:\s*actions/setup-go@' .github/workflows/*.yaml || true
echo
echo "== checkout steps: show 'with:' block if present nearby (test.yaml) =="
rg -n --context 6 'uses:\s*actions/checkout@' .github/workflows/test.yamlRepository: OneBusAway/docker
Length of output: 2248
Harden GitHub Actions: pin action SHAs and disable checkout credential persistence.
.github/workflows/test.yaml uses tag-based actions/checkout@v4 and actions/setup-go@v5, and none of the checkout steps set persist-credentials: false (same unpinned checkout pattern exists in .github/workflows/docker.yaml).
Suggested patch
- name: Checkout code
- uses: actions/checkout@v4
+ uses: actions/checkout@<full-commit-sha>
+ with:
+ persist-credentials: false
- name: Set up Go
- uses: actions/setup-go@v5
+ uses: actions/setup-go@<full-commit-sha>
with:
go-version: "1.22"🧰 Tools
🪛 zizmor (1.25.2)
[warning] 14-15: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 15-15: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 18-18: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/test.yaml around lines 14 - 19, Replace tag-based GitHub
Actions and enable non-persistent checkout: change uses: actions/checkout@v4 and
uses: actions/setup-go@v5 to pinned commit SHAs for those actions, and add
persist-credentials: false to the checkout step (the actions/checkout usage) to
disable credential persistence; apply the same changes to the other workflow
referenced (the actions/checkout step in the docker workflow). Ensure you update
the specific occurrences of "actions/checkout" and "actions/setup-go" in the
workflows so they reference commit SHAs rather than version tags and add the
persist-credentials: false field to each checkout step.
There was a problem hiding this comment.
Deferring this one. No workflow in this repo pins actions to commit SHAs or sets persist-credentials: false — docker.yaml has several tag-pinned actions and there is no dependabot config. Applying it to only the new renderer job would create inconsistency without closing the actual exposure, so this is better handled as a separate repo-wide CI-hardening pass (ideally dependabot-managed) rather than scope-creeping this feature PR.
There was a problem hiding this comment.
@aaronbrethorst, that's a reasonable call — partial hardening of only the new job without addressing the rest of the repo would give a false sense of security without actually reducing the attack surface. A dependabot-managed, repo-wide pass is the right approach.
Would you like me to open a follow-up GitHub issue to track the repo-wide CI hardening work (pinning all action SHAs + persist-credentials: false + adding a Dependabot config for Actions)?
Address CodeRabbit review on PR #130: - bootstrap.sh: an explicit GTFS_RT_FEEDS='[]' now disables realtime feeds instead of silently falling back to the legacy single-feed env vars. Existing deployments (legacy vars set, GTFS_RT_FEEDS unset) are unaffected; whitespace-only values still fall through. Also corrects the status log to read accurately for any feed count (0, 1, or N). - test.yaml: add least-privilege 'permissions: contents: read' to the renderer job.
A runnable deployment example that exercises GTFS_RT_FEEDS with two agencies: King County Metro (agency 1) and Pierce Transit (agency 3). Static data comes from the consolidated Puget Sound GTFS feed (single zip, so the existing single-feed bundle builder handles both agencies). Two GtfsRealtimeSource beans are configured via GTFS_RT_FEEDS. oba_app builds from ../../oba rather than the published 2.7.1-latest image, since GTFS_RT_FEEDS support is not in a published release yet. Verified locally: bin/validate.sh passes; realtime vehicles and predicted trip status work for both agencies.
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
docs/superpowers/specs/2026-05-23-multi-gtfs-rt-feeds-design.md (1)
9-9: ⚡ Quick winAvoid machine-local absolute paths in the design spec.
/Users/aaron/repos/...is environment-specific and gets stale quickly; prefer repo-relative naming only.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/superpowers/specs/2026-05-23-multi-gtfs-rt-feeds-design.md` at line 9, Replace the machine-local absolute path in the spec with a repo-relative reference so the document is portable; specifically, change occurrences like `/Users/aaron/repos/onebusaway/docker` to a repo-relative form such as `onebusaway/docker` (or `./onebusaway/docker`) in the section describing the change to generate one `GtfsRealtimeSource` per feed driven by `GTFS_RT_FEEDS`, ensuring the spec references only project-relative locations while keeping mentions of `GtfsRealtimeSource` and `GTFS_RT_FEEDS` intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/superpowers/plans/2026-05-23-multi-gtfs-rt-feeds-docker.md`:
- Around line 187-191: The snippet treats explicit GTFS_RT_FEEDS='[]' as falling
through to the legacy branch; change the elif so legacy normalization runs only
when GTFS_RT_FEEDS is unset/empty (not when it's "[]"). Concretely, keep the
first if (check GTFS_RT_FEEDS non-empty and not "[]"), but change the elif to
require GTFS_RT_FEEDS be empty/unset (e.g. use [ -z "$GTFS_RT_FEEDS" ] && ([ -n
"$TRIP_UPDATES_URL" ] || [ -n "$VEHICLE_POSITIONS_URL" ])) so that explicit "[]"
goes to the no-feeds path and only a truly missing GTFS_RT_FEEDS triggers legacy
normalization; update references to GTFS_RT_FEEDS, TRIP_UPDATES_URL,
VEHICLE_POSITIONS_URL and FEEDS_JSON accordingly.
In `@docs/superpowers/specs/2026-05-23-multi-gtfs-rt-feeds-design.md`:
- Around line 84-87: The current shell snippet treats the literal string "[]" as
unset; change the if-condition to test whether GTFS_RT_FEEDS is set at all (not
whether it is non-empty) so any explicit GTFS_RT_FEEDS value — including "[]" —
takes precedence over legacy normalization; update the branch around
GTFS_RT_FEEDS, FEEDS_JSON, and the legacy vars (TRIP_UPDATES_URL,
VEHICLE_POSITIONS_URL) so a set GTFS_RT_FEEDS always wins and prevents falling
back to legacy single-feed normalization.
- Around line 52-68: The fenced code block in the spec is missing a language tag
(MD040); update the opening triple-backtick for that diagram to include a
language identifier such as "text" (e.g., change ``` to ```text) so the linter
recognizes it; make the edit in the fenced block that starts with "OBACloud
accordion editor" in the document so the diagram is fenced as text.
---
Nitpick comments:
In `@docs/superpowers/specs/2026-05-23-multi-gtfs-rt-feeds-design.md`:
- Line 9: Replace the machine-local absolute path in the spec with a
repo-relative reference so the document is portable; specifically, change
occurrences like `/Users/aaron/repos/onebusaway/docker` to a repo-relative form
such as `onebusaway/docker` (or `./onebusaway/docker`) in the section describing
the change to generate one `GtfsRealtimeSource` per feed driven by
`GTFS_RT_FEEDS`, ensuring the spec references only project-relative locations
while keeping mentions of `GtfsRealtimeSource` and `GTFS_RT_FEEDS` intact.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 1284de51-bee7-4d4a-99a9-a83470716021
📒 Files selected for processing (6)
.github/workflows/test.yamldeployment-examples/multiple-rt-feeds/README.mddeployment-examples/multiple-rt-feeds/docker-compose.yamldocs/superpowers/plans/2026-05-23-multi-gtfs-rt-feeds-docker.mddocs/superpowers/specs/2026-05-23-multi-gtfs-rt-feeds-design.mdoba/bootstrap.sh
| if [ -n "$GTFS_RT_FEEDS" ] && [ "$GTFS_RT_FEEDS" != "[]" ]; then | ||
| FEEDS_JSON="$GTFS_RT_FEEDS" | ||
| echo "GTFS_RT_FEEDS is set. Rendering multiple GTFS-RT feeds." | ||
| elif [ -n "$TRIP_UPDATES_URL" ] || [ -n "$VEHICLE_POSITIONS_URL" ]; then | ||
| echo "Legacy single-feed GTFS-RT env vars are set. Normalizing into one feed." |
There was a problem hiding this comment.
Explicit GTFS_RT_FEEDS='[]' semantics in this snippet conflict with the stated behavior
This condition allows legacy fallback when GTFS_RT_FEEDS is explicitly [], but the PR summary says [] should disable realtime feeds. Please update this plan snippet so explicit [] routes to the no-feeds path, not legacy normalization.
Suggested doc snippet adjustment
-if [ -n "$GTFS_RT_FEEDS" ] && [ "$GTFS_RT_FEEDS" != "[]" ]; then
+if [ -n "$GTFS_RT_FEEDS" ]; then
+ if [ "$GTFS_RT_FEEDS" = "[]" ]; then
+ FEEDS_JSON="[]"
+ echo "GTFS_RT_FEEDS is explicitly empty. No realtime feeds will be configured."
+ else
+ FEEDS_JSON="$GTFS_RT_FEEDS"
+ echo "GTFS_RT_FEEDS is set. Rendering multiple GTFS-RT feeds."
+ fi
- FEEDS_JSON="$GTFS_RT_FEEDS"
- echo "GTFS_RT_FEEDS is set. Rendering multiple GTFS-RT feeds."
elif [ -n "$TRIP_UPDATES_URL" ] || [ -n "$VEHICLE_POSITIONS_URL" ]; then🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/plans/2026-05-23-multi-gtfs-rt-feeds-docker.md` around lines
187 - 191, The snippet treats explicit GTFS_RT_FEEDS='[]' as falling through to
the legacy branch; change the elif so legacy normalization runs only when
GTFS_RT_FEEDS is unset/empty (not when it's "[]"). Concretely, keep the first if
(check GTFS_RT_FEEDS non-empty and not "[]"), but change the elif to require
GTFS_RT_FEEDS be empty/unset (e.g. use [ -z "$GTFS_RT_FEEDS" ] && ([ -n
"$TRIP_UPDATES_URL" ] || [ -n "$VEHICLE_POSITIONS_URL" ])) so that explicit "[]"
goes to the no-feeds path and only a truly missing GTFS_RT_FEEDS triggers legacy
normalization; update references to GTFS_RT_FEEDS, TRIP_UPDATES_URL,
VEHICLE_POSITIONS_URL and FEEDS_JSON accordingly.
| ``` | ||
| OBACloud accordion editor | ||
| │ (global: base_image, timezone · repeatable feeds) | ||
| ▼ | ||
| DockerfileConfig.feeds ── GtfsRtFeed StoreModel array, persisted in existing JSONB column | ||
| │ | ||
| ▼ Dockerfiles::GenerateObaApi | ||
| ENV GTFS_RT_FEEDS='[{…},{…}]' ◄── THE CROSS-REPO CONTRACT | ||
| │ pushed to OneBusAway/obacloud-dockerfiles → Render builds image | ||
| ▼ | ||
| bootstrap.sh ── if $GTFS_RT_FEEDS set → use it; else normalize legacy single-feed vars into a 1-element FEEDS array | ||
| │ hands { "FEEDS": [...] } to hbs_renderer (raymond) | ||
| ▼ | ||
| data-sources.xml.hbs ── {{#each FEEDS}} → one <bean class="GtfsRealtimeSource"> per feed | ||
| ▼ | ||
| OneBusAway runs with N realtime feeds | ||
| ``` |
There was a problem hiding this comment.
Add a language tag to the fenced code block.
This block is missing a fence language (MD040), which will trip markdown linting.
Suggested diff
-```
+```text
OBACloud accordion editor
│ (global: base_image, timezone · repeatable feeds)
▼
DockerfileConfig.feeds ── GtfsRtFeed StoreModel array, persisted in existing JSONB column
│
▼ Dockerfiles::GenerateObaApi
ENV GTFS_RT_FEEDS='[{…},{…}]' ◄── THE CROSS-REPO CONTRACT
│ pushed to OneBusAway/obacloud-dockerfiles → Render builds image
▼
bootstrap.sh ── if $GTFS_RT_FEEDS set → use it; else normalize legacy single-feed vars into a 1-element FEEDS array
│ hands { "FEEDS": [...] } to hbs_renderer (raymond)
▼
data-sources.xml.hbs ── {{`#each` FEEDS}} → one <bean class="GtfsRealtimeSource"> per feed
▼
OneBusAway runs with N realtime feeds</details>
<!-- suggestion_start -->
<details>
<summary>📝 Committable suggestion</summary>
> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
```suggestion
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 52-52: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/specs/2026-05-23-multi-gtfs-rt-feeds-design.md` around lines
52 - 68, The fenced code block in the spec is missing a language tag (MD040);
update the opening triple-backtick for that diagram to include a language
identifier such as "text" (e.g., change ``` to ```text) so the linter recognizes
it; make the edit in the fenced block that starts with "OBACloud accordion
editor" in the document so the diagram is fenced as text.
| if [ -n "$GTFS_RT_FEEDS" ] && [ "$GTFS_RT_FEEDS" != "[]" ]; then | ||
| FEEDS_JSON="$GTFS_RT_FEEDS" | ||
| elif [ -n "$TRIP_UPDATES_URL" ] || [ -n "$VEHICLE_POSITIONS_URL" ]; then | ||
| # Normalize legacy single-feed vars into a one-element FEEDS array. |
There was a problem hiding this comment.
GTFS_RT_FEEDS='[]' behavior is documented incorrectly in this snippet.
This condition makes explicit [] fall through to legacy vars when they exist, which contradicts the intended “explicit empty disables realtime feeds” behavior. Update the snippet/decision text so any set GTFS_RT_FEEDS (including []) wins over legacy normalization.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/specs/2026-05-23-multi-gtfs-rt-feeds-design.md` around lines
84 - 87, The current shell snippet treats the literal string "[]" as unset;
change the if-condition to test whether GTFS_RT_FEEDS is set at all (not whether
it is non-empty) so any explicit GTFS_RT_FEEDS value — including "[]" — takes
precedence over legacy normalization; update the branch around GTFS_RT_FEEDS,
FEEDS_JSON, and the legacy vars (TRIP_UPDATES_URL, VEHICLE_POSITIONS_URL) so a
set GTFS_RT_FEEDS always wins and prevents falling back to legacy single-feed
normalization.
Summary
Teaches the image to configure many GTFS-RT realtime feeds instead of just one, while remaining fully backward compatible.
oba/config/onebusaway-transit-data-federation-webapp-data-sources.xml.hbs): the GTFS-RT block now iterates aFEEDSarray ({{#each FEEDS}}) and emits one<bean class="…GtfsRealtimeSource">per feed, with per-feedtripUpdatesUrl/vehiclePositionsUrl/alertsUrl/refreshInterval/agencyIds/headersMap.oba/bootstrap.sh: builds theFEEDSarray — prefers a newGTFS_RT_FEEDSJSON env var, and when it's unset, normalizes the legacy single-feed vars (TRIP_UPDATES_URL,AGENCY_ID_LIST, etc.) into a one-element array. So every already-deployed single-feed Dockerfile keeps building unchanged. Whitespace/emptyGTFS_RT_FEEDSfalls through to the no-feeds path..github/workflows/test.yaml): adds ago test ./oba/config/template_renderer/...job (the renderer tests weren't run in CI before).agencyIdcases.GTFS_RT_FEEDS.Coordination
This is the docker half of a two-repo change (the other half is OBACloud's multi-feed Dockerfile generator). Because
2.7.1-latestis a mutable tag, merge this and cut a release first so2.7.1-latestunderstandsGTFS_RT_FEEDSbefore OBACloud starts emitting it. The change is additive, so existing single-feed Dockerfiles keep working before and after.Test Plan
cd oba/config/template_renderer && go test ./...passes (multi-feed, empty, legacy-normalized, singular agencyId)bash -n oba/bootstrap.shclean; bothGTFS_RT_FEEDSand legacy paths smoke-tested through the renderer2.7.1-vX.Y.Zrelease and confirmopentransitsoftwarefoundation/onebusaway-api-webapp:2.7.1-latestis republishedSummary by CodeRabbit
New Features
Documentation
Tests
Chores