Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"@openchoreo/backstage-plugin-backend": "workspace:^",
"@openchoreo/backstage-plugin-catalog-backend-module": "workspace:^",
"@openchoreo/backstage-plugin-catalog-backend-module-openchoreo-users": "workspace:^",
"@openchoreo/backstage-plugin-jenkins-backend-conditional": "workspace:^",
"@openchoreo/backstage-plugin-openchoreo-ci-backend": "workspace:^",
"@openchoreo/backstage-plugin-openchoreo-observability-backend": "workspace:^",
"@openchoreo/backstage-plugin-permission-backend-module-openchoreo-policy": "workspace:^",
Expand Down
4 changes: 2 additions & 2 deletions packages/backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ backend.add(
backend.add(import('@openchoreo/backstage-plugin-openchoreo-ci-backend'));

// External CI Platform Integrations
// Jenkins: Handles missing config gracefully (API calls fail, not startup)
backend.add(import('@backstage-community/plugin-jenkins-backend'));
// Jenkins: Conditional wrapper - only initializes if jenkins.baseUrl config exists
backend.add(import('@openchoreo/backstage-plugin-jenkins-backend-conditional'));
// GitLab: Requires integrations.gitlab config at startup. Uncomment after configuring in app-config.local.yaml
// For production, config is in app-config.production.yaml with Helm-injected env vars
// backend.add(import('@immobiliarelabs/backstage-plugin-gitlab-backend'));
Expand Down
1 change: 1 addition & 0 deletions plugins/jenkins-backend-conditional/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
38 changes: 38 additions & 0 deletions plugins/jenkins-backend-conditional/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "@openchoreo/backstage-plugin-jenkins-backend-conditional",
"version": "0.1.0",
"license": "Apache-2.0",
"private": true,
"description": "Conditional Jenkins backend plugin that only initializes when Jenkins configuration exists",
"main": "src/index.ts",
"types": "src/index.ts",
"publishConfig": {
"access": "public",
"main": "dist/index.cjs.js",
"types": "dist/index.d.ts"
},
"backstage": {
"role": "backend-plugin",
"pluginId": "jenkins"
},
"scripts": {
"start": "backstage-cli package start",
"build": "backstage-cli package build",
"lint": "backstage-cli package lint",
"test": "backstage-cli package test",
"clean": "backstage-cli package clean",
"prepack": "backstage-cli package prepack",
"postpack": "backstage-cli package postpack"
},
"dependencies": {
"@backstage-community/plugin-jenkins-backend": "^0.24.1",
"@backstage/backend-plugin-api": "^1.1.1",
"@backstage/plugin-catalog-node": "^1.16.1"
},
"devDependencies": {
"@backstage/cli": "^0.34.3"
},
"files": [
"dist"
]
}
1 change: 1 addition & 0 deletions plugins/jenkins-backend-conditional/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { jenkinsBackendConditional as default } from './plugin';
74 changes: 74 additions & 0 deletions plugins/jenkins-backend-conditional/src/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import {
coreServices,
createBackendPlugin,
} from '@backstage/backend-plugin-api';
import { catalogServiceRef } from '@backstage/plugin-catalog-node';

/**
* Conditional Jenkins backend plugin that only initializes when Jenkins
* configuration exists. This prevents startup failures when Jenkins is not
* configured (e.g., when backstage.externalCI.jenkins.enabled=false in Helm).
*/
export const jenkinsBackendConditional = createBackendPlugin({
pluginId: 'jenkins',
register(env) {
env.registerInit({
deps: {
config: coreServices.rootConfig,
logger: coreServices.logger,
httpRouter: coreServices.httpRouter,
auth: coreServices.auth,
httpAuth: coreServices.httpAuth,
permissions: coreServices.permissions,
discovery: coreServices.discovery,
catalog: catalogServiceRef,
},
async init({
config,
logger,
httpRouter,
auth,
httpAuth,
permissions,
discovery,
catalog,
}) {
const jenkinsBaseUrl = config.getOptionalString('jenkins.baseUrl');

if (!jenkinsBaseUrl) {
logger.info(
'Jenkins backend disabled - no jenkins.baseUrl configuration found',
);
return;
}

// Dynamically import Jenkins components to build the router
const { JenkinsBuilder, DefaultJenkinsInfoProvider } = await import(
'@backstage-community/plugin-jenkins-backend'
);

const jenkinsInfoProvider = DefaultJenkinsInfoProvider.fromConfig({
config,
catalog,
discovery,
auth,
httpAuth,
logger,
});

const { router } = await JenkinsBuilder.createBuilder({
config,
logger,
permissions,
jenkinsInfoProvider,
discovery,
auth,
httpAuth,
}).build();

httpRouter.use(router);
logger.info('Jenkins backend plugin initialized');
},
});
},
});
Loading