I’m trying to chain two reusable GitHub Actions workflows:
Workflow A (secrets.yaml) → fetches secrets from Vault
Workflow B (build.yaml) → needs the output DOCKER_CONFIG generated by workflow A
My caller workflow looks like this:
first:
uses: project/continuous-integration/.github/workflows/secrets.yaml@main
with:
vault_url: "https://..."
secrets:
TOKEN: ${{ secrets.TOKEN }}
second:
needs: first
uses: project/continuous-integration/.github/workflows/build.yaml@main
with:
# … build inputs …
secrets:
DOCKER_CONFIG: ${{ needs.first.outputs.DOCKER_CONFIG }}
And inside secrets.yaml:
workflow_call:
inputs:
vault_url:
required: true
type: string
secrets:
TOKEN:
required: true
outputs:
DOCKER_CONFIG:
value: ${{ jobs.fetch.outputs.DOCKER_CONFIG }}
jobs:
fetch:
runs-on: ubuntu-latest
outputs:
DOCKER_CONFIG: ${{ steps.fetch.outputs.DOCKER_CONFIG }}
steps:
- name: Fetch secrets from Vault
id: fetch
run: |
DOCKER_CONFIG=$(curl ... ) # fetch from Vault
echo "::add-mask::$DOCKER_CONFIG"
if [[ -z "$DOCKER_CONFIG" ]]; then
echo "Missing DOCKER_CONFIG"
exit 1
fi
echo "DOCKER_CONFIG=$DOCKER_CONFIG" >> "$GITHUB_OUTPUT"
What I expected:
needs.first.outputs.DOCKER_CONFIG should provide the value to the second job so I can pass it as a secret.
What actually happens:
I get:
Unexpected value ''
My question:
How can I correctly return an output from a reusable workflow and then pass that value as a secret into another reusable workflow? Is it even allowed to map needs..outputs.* to secrets: of a called workflow?