Objective
A repository at /home/interview/repo contains multiple applications that share common build steps. The team wants to eliminate duplication by creating a centralized reusable workflow. The repository has the upload-artifact action available locally at .github/actions/upload-artifact.
Task
Complete two workflows. First, complete the reusable workflow at .github/workflows/shared-build.yml that accepts an input parameter app-name (type: string), uses container image node:20-slim, runs ./build.sh with the app name, and uploads a build artifact named build-<app-name>. Second, complete the caller workflow at .github/workflows/deploy.yml that triggers on push and calls the reusable workflow with app-name: "frontend".
File Path
- Reusable workflow:
/home/interview/repo/.github/workflows/shared-build.yml
- Caller workflow:
/home/interview/repo/.github/workflows/deploy.yml
- Build script:
/home/interview/repo/build.sh
name: Shared Build Workflow
on:
workflow_call:
inputs:
app-name:
required: true
type: string
jobs:
build:
runs-on: ubuntu-latest
container:
image: node:20-slim
steps:
- uses: actions/checkout@v4
- name: Run build script
run: ./build.sh ${{ inputs.app-name }}
- name: Upload build artifact
uses: ./.github/actions/upload-artifact
with:
name: build-${{ inputs.app-name }}
path: build-output.txt
Caller workflow (deploy.yml):
name: Deploy Workflow
on:
push:
jobs:
call-build:
uses: ./.github/workflows/shared-build.yml
with:
app-name: "frontend"
Explanation
Step 1: Reusable Workflow Trigger
on:
workflow_call:
inputs:
app-name:
required: true
type: string
workflow_call makes this a reusable workflow. It can't be triggered directly by events like push. Instead, other workflows call it. The inputs block defines parameters the caller must provide. app-name is required and must be a string.
Step 2: Using Input in Steps
- name: Run build script
run: ./build.sh ${{ inputs.app-name }}
- name: Upload build artifact
uses: ./.github/actions/upload-artifact
with:
name: build-${{ inputs.app-name }}
path: build-output.txt
${{ inputs.app-name }} reads the value passed by the caller. If the caller sends "frontend", the build script runs as ./build.sh frontend and the artifact is named build-frontend.
Step 3: Caller Workflow
jobs:
call-build:
uses: ./.github/workflows/shared-build.yml
with:
app-name: "frontend"
The caller uses uses: with the path to the reusable workflow (not a step action, but a workflow file). The with block passes the input parameters. Multiple callers can reuse the same workflow with different app names.