Skip to content

HowToAddNewTransitAgencyModule

Mathieu Méa edited this page Feb 26, 2026 · 22 revisions

How to add new transit agency module (WIP)

Last update: February 2026

Git repository setup

  • Pick project directory ID:

2 letter country code + city/area name + agency name + transport mode (ca-city-transit-agency-bus)

  • (Alternative: use an existing module repo code as a template/starting point)
  • Create new git repository https://github.com/mtransitapps/ca-city-transit-agency-bus-android with default branch master (default for mtransitapps org) and a README or LICENSE to have 1 commit on the default branch or use git commit --allow-empty -m "First commit" & git push after cloning (gh repo create)
gh repo create mtransitapps/ca-city-transit-agency-bus-android --public --add-readme --license=apache-2.0
git clone git@github.com:mtransitapps/ca-city-transit-agency-bus-gradle.git

Agency config setup

  • Add a config directory with the necessary files
    • agency_name: all valid agency names from short to long
    • cities: static list of cities deserved by the agency
    • input_url: GTFS static url
    • input_url_next: (optional) another GTFS static url for future schedule
    • parent_agency_name: (optional) all valid parent agency names from short to long
    • parent_agency_color: (optional) the parent agency color
    • pkg: package name for Google Play Store like org.mtransit.android.ca_city_transit_agency_bus
    • source_url: web page URL where the GTFS static feed is shared
    • state: (optional) state/territories/provinces names from short to long
    • gtfs:
      • agency.json: JSON file containing agency settings (source)
        • target_route_type_id: (required) route type integer from GTFS Static routes.route_type
        • default_color: (required) default color if not extracted from routes colors
        • default_strings_cleaner_enabled: (recommended) default string cleaner enabled/disabled (based on language/country/field)
        • default_color_enabled: (recommended) default color enabled/disabled for agency (based on routes colors)
        • service_id_cleanup_regex: (recommended) regex to clean service_id so it's more stable across schedule changes
        • service_id_clean_merged: (recommended) remove _merged_* from service_id
        • ...
      • route.json: JSON file containing route settings (source)
        • default_route_id_enabled: (recommanded) default route ID number generated from routes.route_id string
        • use_route_short_name_for_route_id: (recommanded) generate route ID number from routes.route_short_name instead of routes.route_id
        • [route/trip/stop]_id_cleanup_regex: (recommended) regex to clean [route/trip/stop]_id so it's more stable across schedule changes
        • [route/trip/stop]_id_clean_merged: (recommended) remove _merged_* from [route/trip/stop]_id
        • direction_finder_enabled: (recommended) turn on direction string finder from trips.trip_headsign
        • ...
      • (only set values when different from default)
      • (to add comments to the JSON config related to a field: append _comment the field name like field_name_comment for comments about field_name)
  • Add an app-android directory with the necessary files
    • src/main/res/values/
      • route/direction/stop agencies:
        • gtfs_rts_values.xml: GTFS static settings (source)
          • gtfs_rts_db_version: integer that will be automatically overwritten (0)
          • gtfs_rts_contact_us[_fr]: string with the URL of the contact us web page
          • gtfs_rts_fares[_fr]: string with the URL of the fares web page
        • gtfs_real_time_values.xml: GTFS Real-Time settings (source)
        • next_bus_values.xml: Next Bus settings (source)
      • bikes agencies:
        • bike_station_values.xml: GBFS settings (source)
      • common:
        • instagram_values.xml: Instagram news settings (source) (not working at the moment)
        • rss_values.xml: RSS news settings (source)
        • twitter_values.xml: Twitter/X news settings (source)
        • youtube_values.xml: YouTube news settings (source)

Initial pull request

../other_directory/commons/code_setup.sh
  • verify generated files (git submodules...) and stage all current changes with git add .
  • (RDS agencies only) <- this should be done automatically when opening the PR
    • download input data with ./download_only.sh
    • prepare downloaded input data with ./prepare_only.sh
    • parse current data with ./parse_current.sh
    • parse next data with ./parse_next.sh
    • verify and stage all new changes with with git add .
  • Create "setup" branch with git checkout -b setup
  • Commit and push staged changes with git commit -m "Setup" && git push
  • Open pull request for this branch with gh pr create
  • (Create app screenshots now locally? with debug build?)
  • Once PR looks good, it can be merged.
  • Then mannualy trigger mt-sync-code-data.yml workflow to generate 1st GitHub release with an release APK asset

Play Store setup

(need Play Store console access)

  • Create new app on Play Store console
  • Test and release
    • Setup
      • App Signing: do NOT use Play App Signing, instead re-use signing key from main "MonTransit" app
    • Production
      • Countries/regions: target All countries/regions
    • Testing
      • Closed testing:
        • Alpha > Manage track
          • Testers:
            • Email lists: MonTransit Alpha & MonTransit Team
        • Create track with name Beta (Private):
          • Testers:
            • Google Groups: montransit-beta@googlegroups.com
            • Feedback URL https://groups.google.com/g/montransit-beta
  • ... (WIP)

Alpha/Beta (private) release

  • Update wiki/BETA to add the app
  • Inside the /config/store directory, add:
    • alpha: empty file presence indicating to automation that this module is available in Alpha channel
    • beta-private: empty file presence indicating to automation that this module is available in Beta (Private) channel

App screenshots

  • Using a physical device connected with USB or an emulator.
  • Make sure the latest Play Store version of the main app is installed.
  • Install the release build of the app from the Play Store (Alpha/Beta channel)
  • Make screenshots for the default language (en-US):
./commons-android/pub/module-app-screenshot.sh en-US phone 1
./commons-android/pub/module-app-screenshot.sh en-US phone 2
./commons-android/pub/module-app-screenshot.sh en-US phone 3
  • If the module supports french, make screenshots for the french language (fr-FR):
./commons-android/pub/module-app-screenshot.sh fr-FR phone 1
./commons-android/pub/module-app-screenshot.sh fr-FR phone 2
./commons-android/pub/module-app-screenshot.sh fr-FR phone 3
  • Commit the app screenshots in /app-android/src/main/play/listings/*/graphics/*-screenshots

Production release

  • Check if the Play Store listing looks good
  • Publish in Production on the Play Store:
    • Test and release
      • Latest releases and bundles
        • Select the -> of the Beta (Private) track
        • Click on Promote release -> Production
        • Click on Next then Save
        • Click on Go to overview to go to
    • Publishing overview
      • Click on Send * change(s) for review
  • Wait for the app to be released in Production and visible signed-out Play Store

Post production release tasks

Related

Clone this wiki locally