Skip to content

Centralise deployment of per-customer Forge app (Jira integration) builds #59

Description

@matthewelwell

Background

We currently maintain bespoke Forge app deployments for each self-hosted / private-cloud Flagsmith customer that uses the Jira integration. To do so, the deployer hand-edits values in this repo before running forge deploy:

  • flagsmith-jira-app/manifest.ymlapp.id and permissions.external.fetch.backend
  • flagsmith-jira-app/src/common.tsFLAGSMITH_API_V1 and FLAGSMITH_APP

This works once, but the resulting customer apps then drift from main because there is no automation to redeploy them. The hand-edited values also can't live in this public repo without leaking customer information.

Goal

  1. Make the public repo deployable to any backend without code edits.
  2. Keep customer identity (app IDs, hostnames) out of the public repo.
  3. Automatically redeploy every customer app when a new release is cut.
  4. Sit back and relax.

Proposed changes

1. Parameterise the manifest

In flagsmith-jira-app/manifest.yml, replace the hard-coded app.id and the external.fetch.backend entry with manifest variables, and declare them under environment.variables with SaaS defaults so a vanilla checkout still deploys to the marketplace app:

app:
  id: ari:cloud:ecosystem::app/${FORGE_APP_ID}
permissions:
  external:
    fetch:
      backend:
        - ${FLAGSMITH_BACKEND_HOST}
environment:
  variables:
    - key: FORGE_APP_ID
      default: 9ea1f892-1356-44bd-9ac8-684abf3a5714
    - key: FLAGSMITH_BACKEND_HOST
      default: api.flagsmith.com

Manifest variables are substituted by the Forge CLI from the shell environment at deploy time. See Forge manifest variables.

2. Move the frontend URLs out of source

Resolve the existing TODO at flagsmith-jira-app/src/common.ts:4 by reading FLAGSMITH_API_V1 and FLAGSMITH_APP from process.env in the backend resolver, with fall-backs to the SaaS values. Expose them to the frontend via a resolver call (frontend code can't access process.env directly). These are set per Forge environment via:

forge variables set FLAGSMITH_API_V1 https://api.flags.example.com/api/v1
forge variables set FLAGSMITH_APP    https://flags.example.com

3. Private customer config

Store one env file per customer in Flagsmith/infrastructure for each customer. Each file holds only what is needed at deploy time:

FORGE_APP_ID=…
FLAGSMITH_BACKEND_HOST=…
FLAGSMITH_API_V1=…
FLAGSMITH_APP=…
FORGE_EMAIL=…           # Flagsmith service-account email

Note that FORGE_API_TOKEN would still need to live as a Github Secret in that repository, since this is an actual secret value.

4. Automated redeployment

Add a GitHub Actions workflow to each repository. One here that sends the dispatch notification on a tag being created, the other in the Flagsmith/infrastructure repository that uses a repository_dispatch to listen for the notification. The workflow in the Flagsmith/infrastructure repository should look something like:

  1. Checks out the public repo at the release tag.
  2. For each customer config file: exports the env vars, runs the forge variables set commands for the runtime values, then forge deploy --environment production --non-interactive.

5. Migrate existing customer apps

For each of the existing private-cloud customer apps:

  1. Identify the live app.id via forge list against the Flagsmith dev account.
  2. Capture its current backend host and Flagsmith URLs from whatever is deployed today.
  3. Author the customer's env file in the private config repo.
  4. Run the new CI workflow once manually to confirm the deploy is a no-op (or just brings them up to current main).
  5. Delete any local branches / forks that were holding the hand-edited values.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions