Scaffolder Utility Actions logo

Backstage Scaffolder Utility Actions

Created by Roadie

Scaffolder utility actions is a set of extra actions for the Backstage Scaffolder. It gives you practical building blocks for the steps in your software templates. You can drop these actions into a flow to handle common file and data tasks without writing custom code for each template.

At a high level, it helps you work with files and structured data. You can zip files, pause a workflow for a set time, parse JSON or YAML, serialize data to JSON or YAML, and transform content with JSONata. You can merge values into existing JSON or YAML, append or write files, and replace text across files. These actions are small and focused. You can combine them to shape the workspace before you publish code or create a pull request with other actions.

Typical use cases include adding a field to package.json, tweaking YAML settings across many services, creating an archive from generated files, or massaging template output before the next step. It is a good fit when you want repeatable edits that are safe and testable in Scaffolder templates.

The plugin is maintained by Roadie. If you run Backstage yourself, this package can cut down on glue code in templates and make common tasks easy to reuse. It keeps your scaffolder flows clear, short, and dependable.

Installation Instructions

These instructions apply to self-hosted Backstage only. To use this plugin on Roadie, visit the docs.

These actions run on the backend. You call them from templates in the Create page.

Classic backend

Step 1
Add the package in the backend workspace.

Copy
cd packages/backend
yarn add @roadiehq/scaffolder-backend-module-utils

Step 2
Register the actions in the backend Scaffolder plugin file. Open this file
packages/backend/src/plugins/scaffolder.ts

Import the action factories at the top of the file.

Copy
// packages/backend/src/plugins/scaffolder.ts
import {
  createZipAction,
  createSleepAction,
  createWriteFileAction,
  createAppendFileAction,
  createMergeJSONAction,
  createMergeAction,
  createParseFileAction,
  createSerializeYamlAction,
  createSerializeJsonAction,
  createJSONataAction,
  createYamlJSONataTransformAction,
  createJsonJSONataTransformAction,
  createReplaceInFileAction,
} from '@roadiehq/scaffolder-backend-module-utils';
import { createBuiltinActions, createRouter } from '@backstage/plugin-scaffolder-backend';
// other existing imports stay as they are

Add the actions to the Scaffolder setup. Keep your existing variables such as containerRunner and catalogClient.

Copy
// inside your scaffolder plugin setup in packages/backend/src/plugins/scaffolder.ts

const actions = [
  createZipAction(),
  createSleepAction(),
  createWriteFileAction(),
  createAppendFileAction(),
  createMergeJSONAction({}),
  createMergeAction(),
  createParseFileAction(),
  createSerializeYamlAction(),
  createSerializeJsonAction(),
  createJSONataAction(),
  createYamlJSONataTransformAction(),
  createJsonJSONataTransformAction(),
  createReplaceInFileAction(),
  ...createBuiltinActions({
    containerRunner,
    integrations,
    config,
    catalogClient,
    reader,
  }),
];

return await createRouter({
  containerRunner,
  logger,
  config,
  database,
  catalogClient,
  reader,
  actions,
});

Step 3
If your Backstage repo includes the code for the Scaffolder backend package you need to transpile code from node_modules during your build. Update your internal build to handle that.

New backend system

Step 1
Add the package in the backend workspace.

Copy
cd packages/backend
yarn add @roadiehq/scaffolder-backend-module-utils

Step 2
Register the module in the backend entry file. Open this file
packages/backend/src/index.ts

Copy
// packages/backend/src/index.ts
import { createBackend } from '@backstage/backend-defaults';

const backend = createBackend();

backend.add(import('@backstage/plugin-proxy-backend/alpha'));
backend.add(import('@backstage/plugin-scaffolder-backend/alpha'));
backend.add(import('@roadiehq/scaffolder-backend-module-utils'));

backend.start();

Use the actions in a template

Add a template that calls one of the actions. Place the file in a location that your catalog already reads. For example a repository that your catalog rules include.

This example uses the sleep action.

Copy
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: sleep-dummy
  title: Sleep template
  description: A template that sleeps for some seconds
spec:
  owner: roadie
  type: service

  parameters:
    - title: Sleep
      properties:
        amount:
          title: Amount to sleep
          type: number
          description: Will sleep for this amount of seconds

  steps:
    - id: sleep
      name: sleep
      action: roadiehq:utils:sleep
      input:
        amount: ${{ parameters.amount }}

Here is a second example that writes a file.

Copy
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: write-file
  title: Write content to a file
  description: Create or overwrite a file in the workspace
spec:
  owner: roadie
  type: service

  parameters:
    - title: File data
      properties:
        path:
          title: Path
          type: string
        content:
          title: Content
          type: string

  steps:
    - id: writeFile
      name: Create File
      action: roadiehq:utils:fs:write
      input:
        path: ${{ parameters.path }}
        content: ${{ parameters.content }}

Action names you can call in templates include these examples:

Copy
roadiehq:utils:zip  
roadiehq:utils:sleep  
roadiehq:utils:fs:parse  
roadiehq:utils:serialize:yaml  
roadiehq:utils:serialize:json  
roadiehq:utils:jsonata  
roadiehq:utils:jsonata:json:transform  
roadiehq:utils:jsonata:yaml:transform  
roadiehq:utils:json:merge  
roadiehq:utils:merge  
roadiehq:utils:fs:append  
roadiehq:utils:fs:write  
roadiehq:utils:fs:replace

Changelog

This changelog is produced from commits made to the Scaffolder Utility Actions plugin since 8 months ago, and based on the code located here. It may not contain information about all commits. Releases and version bumps are intentionally omitted. This changelog is generated by AI.

Features

  • Add wildcard support in roadiehq:utils:fs:replace action #1816 merged 7 months ago
  • Add option to include dotfiles when globbing in roadiehq:utils:fs:replace action #1906 merged 5 months ago

Bug fixes

  • Replace entire array when mergeArrays is false or not set in utils:merge action #2022 merged 1 month ago
  • Fix merge of empty arrays when preserveYamlComments is true in utils:merge action #2052 merged 18 days ago

Maintenance

  • Update backstage.pluginId to match the createBackendModule pluginId #2042 merged 24 days ago
  • Change package role to backend plugin module #2054 merged 18 days ago
  • Upgrade dependencies #1952 merged 2 months ago
  • Run CI on Node 18 20 22 #1879 merged 6 months ago
  • Remove unused dependencies #1847 merged 7 months ago
  • Revert a previous dependency update #1825 merged 7 months ago

Set up Backstage in minutes with Roadie