Extension Patterns¶
Extend the basic file distribution workflow for more complex scenarios.
General Pattern
These extensions build on the Matrix Distribution pattern. See that page for the underlying concepts.
Multiple File Distribution¶
Conditional Distribution¶
Distribute different files based on repository type:
- name: Check repository type
id: check_type
working-directory: target
run: |
if [ -f "package.json" ]; then
echo "type=nodejs" >> $GITHUB_OUTPUT
elif [ -f "pom.xml" ]; then
echo "type=java" >> $GITHUB_OUTPUT
fi
- name: Copy appropriate files
run: |
if [ "${{ steps.check_type.outputs.type }}" = "nodejs" ]; then
cp node-config.json target/
elif [ "${{ steps.check_type.outputs.type }}" = "java" ]; then
cp java-config.xml target/
fi
Template Rendering¶
Substitute variables in templates:
- name: Render template
run: |
sed "s/{{REPO_NAME}}/${{ matrix.repo.name }}/g" template.txt > target/file.txt
Advanced Template Rendering¶
Use envsubst for multiple variables:
- name: Render template
env:
REPO_NAME: ${{ matrix.repo.name }}
ORG_NAME: your-org
TIMESTAMP: ${{ github.event.head_commit.timestamp }}
run: |
envsubst < template.txt > target/file.txt
Directory Distribution¶
Distribute entire directories:
File Transformation¶
Transform files during distribution:
- name: Transform and copy
run: |
# Convert YAML to JSON
yq -o=json source.yaml > target/config.json
# Minify JavaScript
terser source.js -o target/script.min.js
Selective Repository Targeting¶
Filter repositories by criteria:
- name: Query repositories with topic
run: |
REPOS=$(gh api graphql -f query='
{
search(query: "org:your-org topic:needs-config", type: REPOSITORY, first: 100) {
nodes {
... on Repository {
name
defaultBranchRef { name }
}
}
}
}' --jq '.data.search.nodes | map({name: .name, default_branch: .defaultBranchRef.name})')