{"id":51858582,"url":"https://github.com/stuttgart-things/backstage-claim-machinery-plugin","last_synced_at":"2026-07-24T03:31:08.149Z","repository":{"id":332536195,"uuid":"1134125092","full_name":"stuttgart-things/backstage-claim-machinery-plugin","owner":"stuttgart-things","description":"backstage plugin for claim-machinery","archived":false,"fork":false,"pushed_at":"2026-06-14T11:02:24.000Z","size":71,"stargazers_count":0,"open_issues_count":6,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-14T13:04:58.619Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stuttgart-things.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-14T09:33:26.000Z","updated_at":"2026-04-05T06:06:43.000Z","dependencies_parsed_at":"2026-06-14T13:02:35.223Z","dependency_job_id":null,"html_url":"https://github.com/stuttgart-things/backstage-claim-machinery-plugin","commit_stats":null,"previous_names":["stuttgart-things/backstage-claim-machinery-plugin"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/stuttgart-things/backstage-claim-machinery-plugin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stuttgart-things%2Fbackstage-claim-machinery-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stuttgart-things%2Fbackstage-claim-machinery-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stuttgart-things%2Fbackstage-claim-machinery-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stuttgart-things%2Fbackstage-claim-machinery-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stuttgart-things","download_url":"https://codeload.github.com/stuttgart-things/backstage-claim-machinery-plugin/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stuttgart-things%2Fbackstage-claim-machinery-plugin/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35826032,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-24T02:00:07.870Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-07-24T03:31:06.982Z","updated_at":"2026-07-24T03:31:08.049Z","avatar_url":"https://github.com/stuttgart-things.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Backstage Claim Machinery Integration\n\nThis plugin integrates the Claim Machinery API with Backstage, providing custom scaffolder field extensions and actions for rendering claim templates.\n\n## Features\n\n- **Custom Field Extensions**: Dynamic dropdown for claim templates and auto-generated parameter forms\n- **Backend Action**: Render claim templates via the Claim Machinery API\n- **Template Examples**: Ready-to-use templates for creating merge requests with rendered claims\n- **GitLab Integration**: Automatically create merge requests with rendered manifests\n- **Configurable**: API URL configurable via `app-config.yaml` - no code changes needed\n\n## Components\n\n### Backend Plugin\n- **Custom Scaffolder Action**: `claim-machinery:render`\n- Fetches templates from Claim Machinery API\n- Renders manifests with user-provided parameters\n- Outputs manifest content for subsequent steps\n\n### Frontend Plugin\n- **ClaimMachineryPicker**: Dropdown selector for claim templates\n- **ClaimMachineryParameters**: Dynamic form generator for template parameters\n- Fetches available templates from API\n- Provides real-time parameter validation\n\n## Installation\n\n### Prerequisites\n\n- Backstage instance (v1.x with new backend system)\n- Claim Machinery API accessible from your Backstage backend\n- GitLab integration configured (for merge request templates)\n\n### Step 1: Copy Plugin Files\n\n```bash\n# Set your directories\nBACKSTAGE_DIR=\"/path/to/your/backstage\"\nPLUGIN_DIR=\"/path/to/backstage-claim-machinery-plugin\"\n\n# Copy backend plugin\ncp -r $PLUGIN_DIR/backend/scaffolder-claim-machinery \\\n      $BACKSTAGE_DIR/packages/backend/src/plugins/\n\n# Copy frontend components\nmkdir -p $BACKSTAGE_DIR/packages/app/src/scaffolder\ncp -r $PLUGIN_DIR/frontend/ClaimMachineryPicker \\\n      $BACKSTAGE_DIR/packages/app/src/scaffolder/\n\n# Copy templates\nmkdir -p $BACKSTAGE_DIR/test-templates\ncp $PLUGIN_DIR/templates/*.yaml $BACKSTAGE_DIR/test-templates/\n```\n\n### Step 2: Install Dependencies\n\n```bash\n# Frontend dependencies\ncd $BACKSTAGE_DIR/packages/app\nyarn add @backstage/plugin-scaffolder-react\n\n# Backend dependencies\ncd $BACKSTAGE_DIR/packages/backend\nyarn add fs-extra node-fetch@2\nyarn add -D @types/fs-extra @types/node-fetch\n```\n\n### Step 3: Register Backend Action (New Backend System)\n\nThe plugin includes a `module.ts` that registers the action using the new Backstage backend system.\n\nEdit `packages/backend/src/index.ts`:\n\n```typescript\nimport { createBackend } from '@backstage/backend-defaults';\n\nconst backend = createBackend();\n\n// ... other plugins ...\n\n// scaffolder plugin\nbackend.add(import('@backstage/plugin-scaffolder-backend'));\nbackend.add(import('@backstage/plugin-scaffolder-backend-module-github'));\n\n// claim-machinery custom scaffolder action\nbackend.add(import('./plugins/scaffolder-claim-machinery/module'));\n\n// ... rest of plugins ...\n\nbackend.start();\n```\n\nThe module (`packages/backend/src/plugins/scaffolder-claim-machinery/module.ts`) automatically injects the Backstage config to read the API URL:\n\n```typescript\nimport { createBackendModule, coreServices } from '@backstage/backend-plugin-api';\nimport { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node';\nimport { claimMachineryRenderAction } from './action';\n\nexport default createBackendModule({\n  pluginId: 'scaffolder',\n  moduleId: 'claim-machinery',\n\n  register(env) {\n    env.registerInit({\n      deps: {\n        scaffolderActions: scaffolderActionsExtensionPoint,\n        config: coreServices.rootConfig,\n      },\n      async init({ scaffolderActions, config }) {\n        scaffolderActions.addActions(\n          claimMachineryRenderAction({ config }),\n        );\n      },\n    });\n  },\n});\n```\n\n### Step 4: Register Frontend Field Extensions\n\nCreate an index file to export the field extensions at `packages/app/src/scaffolder/ClaimMachineryPicker/index.ts`:\n\n```typescript\nimport { scaffolderPlugin } from '@backstage/plugin-scaffolder';\nimport { createScaffolderFieldExtension } from '@backstage/plugin-scaffolder-react';\nimport { ClaimMachineryPickerExtension } from './ClaimMachineryPickerExtension';\nimport { ClaimMachineryParametersExtension } from './ClaimMachineryParametersExtension';\n\nexport const ClaimMachineryPickerFieldExtension = scaffolderPlugin.provide(\n  createScaffolderFieldExtension({\n    name: 'ClaimMachineryPicker',\n    component: ClaimMachineryPickerExtension,\n  }),\n);\n\nexport const ClaimMachineryParametersFieldExtension = scaffolderPlugin.provide(\n  createScaffolderFieldExtension({\n    name: 'ClaimMachineryParameters',\n    component: ClaimMachineryParametersExtension,\n  }),\n);\n```\n\nThen register them in `packages/app/src/App.tsx`:\n\n```typescript\nimport { ScaffolderPage, scaffolderPlugin, ScaffolderFieldExtensions } from '@backstage/plugin-scaffolder';\nimport {\n  ClaimMachineryPickerFieldExtension,\n  ClaimMachineryParametersFieldExtension,\n} from './scaffolder/ClaimMachineryPicker';\n\n// ... in your routes ...\n\n\u003cRoute path=\"/create\" element={\u003cScaffolderPage /\u003e}\u003e\n  \u003cScaffolderFieldExtensions\u003e\n    \u003cClaimMachineryPickerFieldExtension /\u003e\n    \u003cClaimMachineryParametersFieldExtension /\u003e\n  \u003c/ScaffolderFieldExtensions\u003e\n\u003c/Route\u003e\n```\n\n### Step 5: Configure Claim Machinery API URL\n\nAdd the configuration to `app-config.yaml`:\n\n```yaml\n# Claim Machinery configuration\nclaimMachinery:\n  apiUrl: ${CLAIM_MACHINERY_API_URL:-http://your-claim-machinery-api:8080}\n\n# Proxy for frontend requests\nproxy:\n  endpoints:\n    '/claim-machinery':\n      target: ${CLAIM_MACHINERY_API_URL:-http://your-claim-machinery-api:8080}\n      changeOrigin: true\n      pathRewrite:\n        '^/api/proxy/claim-machinery': ''\n      allowedHeaders: ['*']\n      credentials: 'dangerously-allow-unauthenticated'\n```\n\nThe API URL can be configured in two ways:\n\n1. **Environment variable** (recommended for different environments):\n   ```bash\n   export CLAIM_MACHINERY_API_URL=http://your-api:8080\n   ```\n\n2. **Direct in app-config.yaml**:\n   ```yaml\n   claimMachinery:\n     apiUrl: http://your-api:8080\n   ```\n\n### Step 6: Add Templates to Catalog\n\nAdd the templates to your `app-config.yaml`:\n\n```yaml\ncatalog:\n  locations:\n    # ... existing locations ...\n\n    # Claim Machinery templates\n    - type: file\n      target: ../../test-templates/claim-template.yaml\n      rules:\n        - allow: [Template]\n    - type: file\n      target: ../../test-templates/claim-to-merge-request.yaml\n      rules:\n        - allow: [Template]\n```\n\n## Configuration Reference\n\n### app-config.yaml\n\n```yaml\n# Claim Machinery API configuration\nclaimMachinery:\n  # The URL of the Claim Machinery API\n  # Used by the backend scaffolder action\n  apiUrl: ${CLAIM_MACHINERY_API_URL:-http://localhost:8080}\n\n# Proxy configuration for frontend requests\nproxy:\n  endpoints:\n    '/claim-machinery':\n      # Should match claimMachinery.apiUrl\n      target: ${CLAIM_MACHINERY_API_URL:-http://localhost:8080}\n      changeOrigin: true\n      pathRewrite:\n        '^/api/proxy/claim-machinery': ''\n      allowedHeaders: ['*']\n      credentials: 'dangerously-allow-unauthenticated'\n```\n\n### Environment Variables\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `CLAIM_MACHINERY_API_URL` | URL of the Claim Machinery API | `http://localhost:8080` |\n\n## Usage\n\n### Using the Custom Field Extensions\n\nIn your scaffolder templates, use the custom fields:\n\n```yaml\nparameters:\n  - title: Claim Configuration\n    properties:\n      claimTemplate:\n        title: Claim Template\n        type: string\n        ui:field: ClaimMachineryPicker\n\n      parameters:\n        title: Template Parameters\n        type: object\n        ui:field: ClaimMachineryParameters\n```\n\n### Using the Backend Action\n\nIn your template steps:\n\n```yaml\nsteps:\n  - id: render\n    name: Render Claim\n    action: claim-machinery:render\n    input:\n      template: ${{ parameters.claimTemplate }}\n      parameters: ${{ parameters.parameters }}\n      outputPath: 'claims'\n\n  # Access the rendered manifest in subsequent steps\n  - id: log\n    name: Show Manifest\n    action: debug:log\n    input:\n      message: ${{ steps['render'].output.manifest }}\n```\n\n### Action Outputs\n\nThe `claim-machinery:render` action provides:\n\n- `manifest`: The full rendered YAML manifest as a string\n- `filePath`: The filename of the saved manifest (e.g., `volumeclaim-simple.yaml`)\n\n## Example Templates\n\n### 1. Simple Claim Rendering (`claim-template.yaml`)\n\nRenders a claim and displays the manifest with options to create a merge request.\n\n### 2. Claim to Merge Request (`claim-to-merge-request.yaml`)\n\nComplete workflow that:\n1. Renders a claim from the API\n2. Creates a GitLab merge request\n3. Commits the manifest to the repository\n4. Provides links to review and merge\n\n## Customization\n\n### Change Target Repository\n\nEdit the templates to point to your repository:\n\n```yaml\n- action: publish:gitlab:merge-request\n  input:\n    repoUrl: your-gitlab.com?owner=your-org\u0026repo=your-repo\n```\n\n### Add Custom Validation\n\nExtend the field components in `frontend/ClaimMachineryPicker/` to add custom validation logic.\n\n## Troubleshooting\n\n### \"socket hang up\" errors\n\nIf you see connection errors, check:\n1. API is accessible from the backend container\n2. Correct hostname is used (not localhost if running in containers)\n3. Firewall/network policies allow connections\n\n### \"Unexpected token '\u003c', \"\u003c!DOCTYPE\"...\" errors\n\nThis means the frontend is getting HTML instead of JSON:\n1. Check proxy configuration in `app-config.yaml`\n2. Verify the backend URL is correct\n3. Check browser network tab for the actual request URL\n\n### Field extensions not showing up\n\n1. Verify `@backstage/plugin-scaffolder-react` is installed\n2. Check field extensions are registered in `App.tsx` inside `\u003cScaffolderFieldExtensions\u003e`\n3. Ensure you're using `scaffolderPlugin.provide()` to create the extensions\n4. Restart the development server\n\n### Dropdown is empty\n\n1. Check `claimMachinery.apiUrl` in `app-config.yaml`\n2. Verify proxy configuration in `app-config.yaml`\n3. Test API manually: `curl http://YOUR-API:8080/api/v1/claim-templates`\n4. Check browser console for errors\n\n### \"Gateway Timeout\" errors\n\n1. Verify the Claim Machinery API is running\n2. Check the API URL is correct in `app-config.yaml`\n3. Ensure network connectivity between Backstage and the API\n\n## Architecture\n\n```\n+----------------------------------------------------------+\n|                    Backstage Frontend                     |\n|  +----------------------------------------------------+  |\n|  |  ClaimMachineryPicker (Dropdown)                   |  |\n|  |  ClaimMachineryParameters (Dynamic Form)           |  |\n|  +----------------------------------------------------+  |\n|                        |                                  |\n|                        | fetch()                          |\n|                        v                                  |\n+----------------------------------------------------------+\n                         |\n                         | HTTP (port 7007)\n                         v\n+----------------------------------------------------------+\n|                    Backstage Backend                      |\n|  +----------------------------------------------------+  |\n|  |  Proxy: /api/proxy/claim-machinery                 |  |\n|  |  Action: claim-machinery:render                    |  |\n|  |  Config: claimMachinery.apiUrl                     |  |\n|  +----------------------------------------------------+  |\n|                        |                                  |\n|                        | HTTP                              |\n|                        v                                  |\n+----------------------------------------------------------+\n                         |\n                         v\n+----------------------------------------------------------+\n|              Claim Machinery API                          |\n|  - GET  /api/v1/claim-templates (list)                   |\n|  - GET  /api/v1/claim-templates/{name} (details)         |\n|  - POST /api/v1/claim-templates/{name}/order (render)    |\n+----------------------------------------------------------+\n```\n\n## API Reference\n\n### Backend Action: `claim-machinery:render`\n\n**Input:**\n- `template` (string, required): Name of the claim template\n- `parameters` (object, optional): Template parameters\n- `outputPath` (string, optional): Directory to save the manifest (default: '.')\n\n**Output:**\n- `manifest` (string): The rendered YAML manifest\n- `filePath` (string): The filename of the saved manifest\n\n**Configuration:**\n- Reads API URL from `claimMachinery.apiUrl` in `app-config.yaml`\n\n### Field Extension: ClaimMachineryPicker\n\nDisplays a dropdown of available claim templates fetched from the API.\n\n**Schema:**\n```yaml\nclaimTemplate:\n  type: string\n  ui:field: ClaimMachineryPicker\n```\n\n### Field Extension: ClaimMachineryParameters\n\nDynamically generates form fields based on the selected template's parameter schema.\n\n**Schema:**\n```yaml\nparameters:\n  type: object\n  ui:field: ClaimMachineryParameters\n```\n\n**Supported Parameter Types:**\n- `string`: Text input\n- `boolean`: Checkbox\n- `array`: Comma-separated text input\n- `enum`: Dropdown selector\n\n## Contributing\n\nTo contribute improvements:\n\n1. Make changes to the components\n2. Test in your Backstage instance\n3. Update documentation\n4. Share your changes\n\n## License\n\nApache-2.0\n\n## Support\n\nFor issues related to:\n- **Claim Machinery API**: Contact your platform team\n- **Backstage Integration**: Check Backstage documentation\n- **This Plugin**: Review troubleshooting section above\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstuttgart-things%2Fbackstage-claim-machinery-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstuttgart-things%2Fbackstage-claim-machinery-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstuttgart-things%2Fbackstage-claim-machinery-plugin/lists"}