diff --git a/.changeset/migrate-1713466095837.md b/.changeset/migrate-1713466095837.md new file mode 100644 index 0000000000..a79280d503 --- /dev/null +++ b/.changeset/migrate-1713466095837.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-jenkins': patch +'@backstage/plugin-jenkins-backend': patch +'@backstage/plugin-jenkins-common': patch +--- + +These packages have been migrated to the [backstage/community-plugins](https://github.com/backstage/community-plugins) repository. diff --git a/plugins/jenkins-backend/README.md b/plugins/jenkins-backend/README.md index 4cca86f86d..a31890d880 100644 --- a/plugins/jenkins-backend/README.md +++ b/plugins/jenkins-backend/README.md @@ -1,255 +1,3 @@ -# Jenkins Plugin (Alpha) +# Deprecated -Welcome to the Jenkins backend plugin! Website: [https://jenkins.io/](https://jenkins.io/) - -This is the backend half of the 2 Jenkins plugins and is responsible for: - -- finding an appropriate instance of Jenkins for an entity -- finding the appropriate job(s) on that instance for an entity -- connecting to Jenkins and gathering data to present to the frontend - -## New Backend System - -The jenkins backend plugin has support for the [new backend system](https://backstage.io/docs/backend-system/), here's how you can set that up: - -In your `packages/backend/src/index.ts` make the following changes: - -```diff - import { createBackend } from '@backstage/backend-defaults'; - const backend = createBackend(); - // ... other feature additions - backend.add(import('@backstage/plugin-jenkins-backend')); - backend.start(); -``` - -## Integrating into a backstage instance - -This plugin needs to be added to an existing backstage instance. - -```bash -# From your Backstage root directory -yarn --cwd packages/backend add @backstage/plugin-jenkins-backend -``` - -Typically, this means creating a `src/plugins/jenkins.ts` file and adding a reference to it to `src/index.ts` - -### jenkins.ts - -```typescript -import { - createRouter, - DefaultJenkinsInfoProvider, -} from '@backstage/plugin-jenkins-backend'; -import { CatalogClient } from '@backstage/catalog-client'; -import { Router } from 'express'; -import { PluginEnvironment } from '../types'; - -export default async function createPlugin( - env: PluginEnvironment, -): Promise { - const catalog = new CatalogClient({ - discoveryApi: env.discovery, - }); - - return await createRouter({ - logger: env.logger, - jenkinsInfoProvider: DefaultJenkinsInfoProvider.fromConfig({ - config: env.config, - catalog, - }), - permissions: env.permissions, - }); -} -``` - -### src/index.ts - -```diff -diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts -index f2b14b2..2c64f47 100644 ---- a/packages/backend/src/index.ts -+++ b/packages/backend/src/index.ts -@@ -22,6 +22,7 @@ import { Config } from '@backstage/config'; - import app from './plugins/app'; -+import jenkins from './plugins/jenkins'; - import scaffolder from './plugins/scaffolder'; -@@ -56,6 +57,7 @@ async function main() { - const authEnv = useHotMemoize(module, () => createEnv('auth')); -+ const jenkinsEnv = useHotMemoize(module, () => createEnv('jenkins')); - const proxyEnv = useHotMemoize(module, () => createEnv('proxy')); -@@ -63,6 +65,7 @@ async function main() { - - const apiRouter = Router(); - apiRouter.use('/catalog', await catalog(catalogEnv)); -+ apiRouter.use('/jenkins', await jenkins(jenkinsEnv)); - apiRouter.use('/scaffolder', await scaffolder(scaffolderEnv)); -``` - -This plugin must be provided with a JenkinsInfoProvider, this is a strategy object for finding the Jenkins instance and job for an entity. - -There is a standard one provided, but the Integrator is free to build their own. - -### DefaultJenkinsInfoProvider - -Allows configuration of either a single or multiple global Jenkins instances and annotating entities with the job name on that instance (and optionally the name of the instance). - -#### Example - Single global instance - -The following will look for jobs for this entity at `https://jenkins.example.com/job/teamA/job/artistLookup-build` - -Config - -```yaml -jenkins: - baseUrl: https://jenkins.example.com - username: backstage-bot - apiKey: 123456789abcdef0123456789abcedf012 - # optionally add extra headers - # extraRequestHeaders: - # extra-header: my-value -``` - -Catalog - -```yaml -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: artist-lookup - annotations: - 'jenkins.io/job-full-name': teamA/artistLookup-build -``` - -The old annotation name of `jenkins.io/github-folder` is equivalent to `jenkins.io/job-full-name` - -#### Example - Multiple global instances - -The following will look for jobs for this entity at `https://jenkins-foo.example.com/job/teamA/job/artistLookup-build` - -Config - -```yaml -jenkins: - instances: - - name: default - baseUrl: https://jenkins.example.com - username: backstage-bot - apiKey: 123456789abcdef0123456789abcedf012 - - name: departmentFoo - baseUrl: https://jenkins-foo.example.com - username: backstage-bot - apiKey: 123456789abcdef0123456789abcedf012 -``` - -Catalog - -```yaml -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: artist-lookup - annotations: - 'jenkins.io/job-full-name': departmentFoo:teamA/artistLookup-build -``` - -If the `departmentFoo:` part is omitted, the default instance will be assumed. - -The following config is an equivalent (but less clear) version of the above: - -```yaml -jenkins: - baseUrl: https://jenkins.example.com - username: backstage-bot - apiKey: 123456789abcdef0123456789abcedf012 - instances: - - name: departmentFoo - baseUrl: https://jenkins-foo.example.com - username: backstage-bot - apiKey: 123456789abcdef0123456789abcedf012 -``` - -### Custom JenkinsInfoProvider - -An example of a bespoke JenkinsInfoProvider which uses an organisation specific annotation to look up the Jenkins info (including jobFullName): - -```typescript -class AcmeJenkinsInfoProvider implements JenkinsInfoProvider { - constructor(private readonly catalog: CatalogClient) {} - - async getInstance(opt: { - entityRef: EntityName; - jobFullName?: string; - }): Promise { - const PAAS_ANNOTATION = 'acme.example.com/paas-project-name'; - - // lookup pass-project-name from entity annotation - const entity = await this.catalog.getEntityByRef(opt.entityRef); - if (!entity) { - throw new Error( - `Couldn't find entity with name: ${stringifyEntityRef(opt.entityRef)}`, - ); - } - - const paasProjectName = entity.metadata.annotations?.[PAAS_ANNOTATION]; - if (!paasProjectName) { - throw new Error( - `Couldn't find paas annotation (${PAAS_ANNOTATION}) on entity with name: ${stringifyEntityRef( - opt.entityRef, - )}`, - ); - } - - // lookup department and team for paas project name - const { team, dept } = this.lookupPaasInfo(paasProjectName); - - const baseUrl = `https://jenkins-${dept}.example.com/`; - const jobFullName = `${team}/${paasProjectName}`; - const username = 'backstage-bot'; - const apiKey = this.getJenkinsApiKey(paasProjectName); - const creds = btoa(`${username}:${apiKey}`); - - return { - baseUrl, - headers: { - Authorization: `Basic ${creds}`, - }, - jobFullName, - }; - } - - private lookupPaasInfo(_: string): { team: string; dept: string } { - // Mock implementation, this would get info from the paas system somehow in reality. - return { - team: 'teamA', - dept: 'DepartmentFoo', - }; - } - - private getJenkinsApiKey(_: string): string { - // Mock implementation, this would get info from the paas system somehow in reality. - return '123456789abcdef0123456789abcedf012'; - } -} -``` - -No config would be needed if using this JenkinsInfoProvider - -A Catalog entity of the following will look for jobs for this entity at `https://jenkins-departmentFoo.example.com/job/teamA/job/artistLookupService` - -```yaml -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: artist-lookup - annotations: - 'acme.example.com/paas-project-name': artistLookupService -``` - -## Jenkins' terminology notes - -The domain model for Jenkins is not particularly clear but for the purposes of this plugin the following model has been assumed: - -Jenkins contains a tree of *job*s which have children of either; other *job*s (making it a _folder_) or *build*s (making it a _project_). -Concepts like _pipeline_ and *view*s are meaningless (pipelines are just jobs for our purposes, views are (as the name suggests) just views of subsets of jobs) - -A _job full name_ is a slash separated list of the names of the job, and the folders which contain it. For example `teamA/artistLookupService/develop`, and the same way that a filesystem path has folders and file names. +This package has been moved to the [backstage-community/plugins](https://github.com/backstage/community-plugins) repository. Migrate to using `@backstage-community/plugin-jenkins-backend` instead. diff --git a/plugins/jenkins-backend/package.json b/plugins/jenkins-backend/package.json index a074ebb333..6e7d3836ed 100644 --- a/plugins/jenkins-backend/package.json +++ b/plugins/jenkins-backend/package.json @@ -3,7 +3,8 @@ "version": "0.4.4", "description": "A Backstage backend plugin that integrates towards Jenkins", "backstage": { - "role": "backend-plugin" + "role": "backend-plugin", + "moved": "@backstage-community/plugin-jenkins-backend" }, "publishConfig": { "access": "public", @@ -56,5 +57,6 @@ "@types/jenkins": "^1.0.0", "@types/supertest": "^2.0.8" }, - "configSchema": "config.d.ts" + "configSchema": "config.d.ts", + "deprecated": "This package has been moved to the backstage/community-plugins repository. You should migrate to using @backstage-community/plugin-jenkins-backend instead." } diff --git a/plugins/jenkins-common/README.md b/plugins/jenkins-common/README.md index 54a79fc287..b22a05247c 100644 --- a/plugins/jenkins-common/README.md +++ b/plugins/jenkins-common/README.md @@ -1,3 +1,3 @@ -# Jenkins Common +# Deprecated -Shared isomorphic code for the Jenkins plugin. +This package has been moved to the [backstage-community/plugins](https://github.com/backstage/community-plugins) repository. Migrate to using `@backstage-community/plugin-jenkins-common` instead. diff --git a/plugins/jenkins-common/package.json b/plugins/jenkins-common/package.json index f29dbfe86b..3f90860b7d 100644 --- a/plugins/jenkins-common/package.json +++ b/plugins/jenkins-common/package.json @@ -2,7 +2,8 @@ "name": "@backstage/plugin-jenkins-common", "version": "0.1.25", "backstage": { - "role": "common-library" + "role": "common-library", + "moved": "@backstage-community/plugin-jenkins-common" }, "publishConfig": { "access": "public", @@ -37,5 +38,6 @@ }, "devDependencies": { "@backstage/cli": "workspace:^" - } + }, + "deprecated": "This package has been moved to the backstage/community-plugins repository. You should migrate to using @backstage-community/plugin-jenkins-common instead." } diff --git a/plugins/jenkins/README.md b/plugins/jenkins/README.md index bdbe0ac0d9..c7a86e2d03 100644 --- a/plugins/jenkins/README.md +++ b/plugins/jenkins/README.md @@ -1,135 +1,3 @@ -# Jenkins Plugin (Alpha) +# Deprecated -Website: [https://jenkins.io/](https://jenkins.io/) - -Last master build -Folder results -Build details -Job builds records -Modify Table Columns - -## Setup - -1. If you have a standalone app (you didn't clone this repo), then do - -```bash -# From your Backstage root directory -yarn --cwd packages/app add @backstage/plugin-jenkins -``` - -2. Add and configure the [jenkins-backend](../jenkins-backend) plugin according to it's instructions - -3. Add the `EntityJenkinsContent` extension to the `CI/CD` page and `EntityLatestJenkinsRunCard` to the `overview` page in the app (or wherever you'd prefer): - -Note that if you configured a custom JenkinsInfoProvider in step 2, you may need a custom isJenkinsAvailable. Also if you're transitioning to a new default branch name, you can pass multiple branch names as a comma-separated list and it will check for each branch name. - -```tsx -// In packages/app/src/components/catalog/EntityPage.tsx -import { - EntityJenkinsContent, - EntityLatestJenkinsRunCard, - isJenkinsAvailable, -} from '@backstage/plugin-jenkins'; - -// You can add the tab to any number of pages, the service page is shown as an -// example here -const serviceEntityPage = ( - - - {/* ... */} - - - - - - - {/* ... */} - - - {/* other tabs... */} - - - - - - {/* ... */} - - - {/* ... */} - -); -``` - -4. Run app with `yarn start` -5. Add the Jenkins folder annotation to your `catalog-info.yaml`. - -Currently, this plugin only supports folders and Git SCM. -Note that if you configured a custom JenkinsInfoProvider in step 2, you may need to use a different annotation scheme here - -```yaml -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: 'your-component' - description: 'a description' - annotations: - jenkins.io/github-folder: 'folder-name/project-name' # deprecated - jenkins.io/job-full-name: 'folder-name/project-name' # use this instead - -spec: - type: service - lifecycle: experimental - owner: your-name -``` - -7. Register your component - -8. Click the component in the catalog. You should now see Jenkins builds, and a - last build result for your master build. - -## Features - -- View all runs inside a folder -- Last build status for specified branch -- View summary of a build - -## Limitations - -- Only works with organization folder projects backed by GitHub -- No pagination support currently, limited to 50 projects - don't run this on a - Jenkins instance with lots of builds - -## EntityJobRunsTable - -- View all builds of a particular job -- shows average build time for successful builds - -## Modify Columns of EntityJenkinsContent - -- now you can pass down column props to show the columns/metadata as per your use case. - -```tsx -export const generatedColumns: TableColumn[] = [ - { - title: 'Timestamp', - field: 'lastBuild.timestamp', - render: (row: Partial) => ( - <> - - {` - ${new Date(row.lastBuild?.timestamp).toLocaleDateString()} - ${new Date(row.lastBuild?.timestamp).toLocaleTimeString()} - `} - - - ), - }, -] - -// ... - -// ... -``` +This package has been moved to the [backstage-community/plugins](https://github.com/backstage/community-plugins) repository. Migrate to using `@backstage-community/plugin-jenkins` instead. diff --git a/plugins/jenkins/package.json b/plugins/jenkins/package.json index 3aff7f3c32..2b969243d6 100644 --- a/plugins/jenkins/package.json +++ b/plugins/jenkins/package.json @@ -3,7 +3,8 @@ "version": "0.9.9", "description": "A Backstage plugin that integrates towards Jenkins", "backstage": { - "role": "frontend-plugin" + "role": "frontend-plugin", + "moved": "@backstage-community/plugin-jenkins" }, "publishConfig": { "access": "public", @@ -62,5 +63,6 @@ "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - } + }, + "deprecated": "This package has been moved to the backstage/community-plugins repository. You should migrate to using @backstage-community/plugin-jenkins instead." }