feat(config): allow specifying env specific config files

this change allows to specify loading of environment specific config
files based on `BACKSTAGE_ENVIRONMENT` environment variable.

relates to #30716

Signed-off-by: Hellgren Heikki <heikki.hellgren@op.fi>
This commit is contained in:
Hellgren Heikki
2025-08-01 15:45:22 +03:00
parent 484e500f49
commit a73f495840
4 changed files with 48 additions and 4 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/config-loader': patch
---
Allow using `BACKSTAGE_ENVIRONMENT` for loading environment specific config files
+17 -4
View File
@@ -16,10 +16,23 @@ allowing for customization.
## Supplying Configuration
Configuration is stored in YAML files where the defaults are `app-config.yaml`
and `app-config.local.yaml` for local overrides. Other sets of files can by
loaded by passing `--config <path>` flags. The configuration files themselves
contain plain YAML, but with support for loading in data and secrets from
various sources using for example `$env` and `$file` keys.
and `app-config.local.yaml` for local overrides. Additionally, it is possible
to define environment based configuration files with `BACKSTAGE_ENVIRONMENT`
environment variable, which will load `app-config.<BACKSTAGE_ENVIRONMENT>.yaml`.
Loading order of these files is as follows:
1. `app-config.yaml`
2. `app-config.<BACKSTAGE_ENVIRONMENT>.yaml`
3. `app-config.local.yaml`
Other sets of files can by loaded by passing `--config <path>` flags.
Read more about the configuration loading order in the
[Configuration Files](./writing.md#configuration-files) section.
The configuration files themselves contain plain YAML, but with support for
loading in data and secrets from various sources using for example
`$env` and `$file` keys.
It is also possible to supply configuration through environment variables, for
example `APP_CONFIG_app_baseUrl=https://staging.example.com`. However these
@@ -89,6 +89,18 @@ describe('ConfigSources', () => {
{ name: 'FileConfigSource', path: `${root}app-config.yaml` },
{ name: 'FileConfigSource', path: `${root}app-config.local.yaml` },
]);
process.env = Object.assign(process.env, { BACKSTAGE_ENVIRONMENT: 'test' });
expect(
mergeSources(
ConfigSources.defaultForTargets({ rootDir: '/', targets: [] }),
),
).toEqual([
{ name: 'FileConfigSource', path: `${root}app-config.yaml` },
{ name: 'FileConfigSource', path: `${root}app-config.test.yaml` },
{ name: 'FileConfigSource', path: `${root}app-config.local.yaml` },
]);
fsSpy.mockRestore();
expect(
@@ -182,6 +182,10 @@ export class ConfigSources {
if (argSources.length === 0) {
const defaultPath = resolvePath(rootDir, 'app-config.yaml');
const localPath = resolvePath(rootDir, 'app-config.local.yaml');
const envPath = resolvePath(
rootDir,
`app-config.${process.env.BACKSTAGE_ENVIRONMENT}.yaml`,
);
const alwaysIncludeDefaultConfigSource =
!options.allowMissingDefaultConfig;
@@ -195,6 +199,16 @@ export class ConfigSources {
);
}
if (process.env.BACKSTAGE_ENVIRONMENT && fs.pathExistsSync(envPath)) {
argSources.push(
FileConfigSource.create({
watch: options.watch,
path: envPath,
substitutionFunc: options.substitutionFunc,
}),
);
}
if (fs.pathExistsSync(localPath)) {
argSources.push(
FileConfigSource.create({