본문 바로가기
WIKI 기술 지식 베이스

Actions

원문 보기 위키 갱신

Actions (알파)

Actions Service는 Backstage 백엔드 플러그인 내에서 등록된 작업(action)을 발견하고 실행하기 위한 표준화된 인터페이스를 제공하는 핵심 서비스예요.

출처: 문서

본문

개요

Actions Service는 Backstage 백엔드 플러그인 내에서 등록된 작업을 발견하고 실행하기 위한 표준화된 인터페이스를 제공하는 핵심 서비스예요. 이 서비스는 Actions Registry Service를 통해 등록된 작업에 대한 소비자 대상 API 역할을 하며, 플러그인이 사용 가능한 작업을 나열하고 적절한 인증과 입력 검증으로 작업을 호출할 수 있게 해요.

작동 방식

Actions Service는 두 가지 주요 메서드를 제공하는 ActionsService 인터페이스를 구현해요:

  • list(): 선언된 시크릿 스키마를 포함한 완전한 메타데이터와 함께 사용 가능한 모든 작업을 검색해요.

  • invoke(): 제공된 입력 데이터와 선택적 시크릿으로 ID별 특정 작업을 실행해요.

이 서비스는 플러그인이 작업을 등록하고 이 서비스를 통해 발견 및 실행에 사용할 수 있게 하는 Actions Registry Service와 함께 작동해요.

작업 식별

작업은 특정 형식을 따르는 고유한 ID로 식별돼요:

  • 모든 작업 ID는 등록한 플러그인의 ID로 접두사가 붙으며 pluginId:actionName 패턴을 따라요.

  • catalog 플러그인이 등록한 fetch-user-info라는 작업은 catalog:fetch-user-info라는 ID를 가져요.

  • actionsRegistryServiceMock을 사용할 때 플러그인 ID 접두사는 test:가 돼요.

이 명명 규칙은 작업 이름이 모든 플러그인에서 전역적으로 고유하도록 보장하고 소유권을 명확히 식별해요.

구성

플러그인별 작업 소스 제한

pluginSources 구성은 어떤 플러그인이 작업을 등록할 수 있는지 제한해요.

backend:  actions:    pluginSources:      - catalog

작업 필터링

플러그인 수준 제한 외에도 Actions Service는 include와 exclude 규칙을 사용한 작업 필터링을 지원해요. 이는 Backstage 인스턴스에서 노출되거나 실행 가능한 작업에 대한 세밀한 제어를 가능하게 해요.

작업은 id(glob 패턴 사용) 또는 attributes(destructive, readOnly, idempotent)로 필터링할 수 있어요.

필터 규칙이 평가되는 방식:

  • 단일 규칙 내에서 id와 attributes는 AND 논리로 결합돼요.

  • 같은 include 또는 exclude 배열의 여러 규칙은 OR 논리로 결합돼요.

특정 작업 포함

backend:  actions:    filter:      include:        # Include all catalog actions that are non-destructive        - id: 'catalog:*'          attributes:            destructive: false        # OR include all fetch actions from any plugin        - id: '*:fetch-*'

특정 작업 제외

backend:  actions:    filter:      exclude:        # Exclude all delete actions from any plugin        - id: '*:delete-*'        # OR exclude all destructive actions        - attributes:            destructive: true

권한

visibilityPermission 필드로 등록된 작업은 권한 프레임워크에 대해 자동으로 검사돼요. 작업을 나열할 때 활성 권한 정책이 거부한 작업은 결과에서 필터링돼요. 거부된 작업을 호출하면 404 Not Found 오류가 반환돼요. 작업에 권한을 구성하는 방법은 Actions Registry 권한 문서를 참고하세요.

서비스 사용

사용 가능한 작업 나열

사용 가능한 모든 작업을 나열하는 예시는 다음과 같아요:

import { ActionsService } from '@backstage/backend-plugin-api';export async function listAvailableActions(  actionsService: ActionsService,  credentials: BackstageCredentials,) {  try {    const { actions } = await actionsService.list({ credentials });    console.log(`Found ${actions.length} available actions:`);    actions.forEach(action => {      console.log(`- ${action.id}: ${action.title}`);      console.log(`  Description: ${action.description}`);      console.log(`  Attributes: ${JSON.stringify(action.attributes)}`);      if (action.schema.input) {        console.log(          `  Input Schema: ${JSON.stringify(action.schema.input, null, 2)}`,        );      }    });    return actions;  } catch (error) {    console.error('Failed to list actions:', error);    throw error;  }}

작업 호출

특정 작업을 실행하는 예시는 다음과 같아요:

import { ActionsService } from '@backstage/backend-plugin-api';export async function executeAction(  actionsService: ActionsService,  actionId: string,  input: JsonObject,  credentials: BackstageCredentials,  secrets?: JsonObject,) {  try {    const { output } = await actionsService.invoke({      id: actionId,      input,      secrets,      credentials,    });    console.log(`Action ${actionId} executed successfully`);    console.log('Output:', JSON.stringify(output, null, 2));    return output;  } catch (error) {    console.error(`Failed to execute action ${actionId}:`, error);    throw error;  }}// Example usageasync function fetchUserInfo(  actionsService: ActionsService,  credentials: BackstageCredentials,) {  const output = await executeAction(    actionsService,    'catalog:fetch-user-info', // Note: Action ID includes plugin prefix    {      userRef: 'user:default/john.doe',      includeGroups: true,    },    credentials,  );  return output;}

시크릿이 있는 작업 호출

일부 작업은 최종 사용자에게 필요한 외부 자격 증명을 위한 secrets 스키마를 선언해요. list()가 반환한 작업 메타데이터의 schema.secrets 필드를 검사해 어떤 작업이 시크릿을 요구하는지 알 수 있어요. 시크릿이 필요한 작업을 호출할 때 입력과 함께 전달하세요:

const { actions } = await actionsService.list({ credentials });const action = actions.find(a => a.id === 'my-plugin:create-issue');if (action?.schema.secrets) {  // This action needs secrets — collect them from the user first  const { output } = await actionsService.invoke({    id: action.id,    input: { repo: 'backstage/backstage', title: 'My issue' },    secrets: { githubToken: collectedToken },    credentials,  });}

시크릿 스키마를 선언하지 않은 작업에 시크릿을 제공하면 호출이 InputError로 거부돼요. 마찬가지로 필수 시크릿을 생략하면 InputError가 발생해요.

작업에서 시크릿을 선언하는 방법에 대한 자세한 내용은 Actions Registry 시크릿 문서를 참고하세요.

모범 사례

작업 설계, 명명 규칙, 스키마 설계에 대한 포괄적인 지침은 Actions Registry 모범 사례 문서를 참고하세요.

더 알아보기 (Learn more)