@@ -21,157 +21,177 @@ inputs:
2121 automerge :
2222 description : ' If true, enable auto-merge on the PR'
2323 default : ' false'
24-
24+ template-ref :
25+ description : ' Tag or branch to check out from the template repository (overrides template-branch)'
26+ required : false
27+
2528runs :
2629 using : " composite"
2730 steps :
31+
32+ # ------------------------------------------------------------
33+ # Checkout target repo
34+ # ------------------------------------------------------------
2835 - name : Checkout the target repo
2936 uses : actions/checkout@v6
3037 with :
3138 token : ${{ inputs.token }}
3239 fetch-depth : 0
33- # persist-credentials: 'false'
3440
3541 - name : Ensure inside a git repository
3642 shell : bash
3743 run : git rev-parse --is-inside-work-tree >/dev/null || { echo "❌ Not in a git repository"; exit 1; }
3844
45+ # ------------------------------------------------------------
46+ # Parse configuration (repository, branch, ref, includes, excludes)
47+ # ------------------------------------------------------------
3948 - name : Parse configuration file
4049 shell : bash
4150 id : config
4251 run : |
4352 CONFIG_FILE="${{ inputs.source }}"
4453 echo "Reading configuration from ${CONFIG_FILE}"
45-
46- if [ ! -f "${CONFIG_FILE}" ]; then
54+
55+ if [[ ! -f "${CONFIG_FILE}" ] ]; then
4756 echo "::error::Configuration file not found: ${CONFIG_FILE}"
4857 exit 1
4958 fi
50-
51- # Install yq if not available
52- if ! command -v yq &> /dev/null; then
53- echo "Installing yq..."
54- wget -qO /tmp/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
59+
60+ # Install yq if needed
61+ if ! command -v yq &>/dev/null; then
62+ wget -qO /tmp/yq https://github.com/mikefarah/yq/releases/download/v4.44.3/yq_linux_amd64
5563 chmod +x /tmp/yq
56- YQ_CMD ="/tmp/yq"
64+ YQ ="/tmp/yq"
5765 else
58- YQ_CMD ="yq"
66+ YQ ="yq"
5967 fi
60-
61- # Read values from config file
62- TEMPLATE_REPO=$($YQ_CMD '.template-repository' "${CONFIG_FILE}")
63- if [ "$TEMPLATE_REPO" = "null" ] || [ -z "$TEMPLATE_REPO" ]; then
64- echo "::error::template-repository not found in ${CONFIG_FILE}"
68+
69+ TEMPLATE_REPO="$($YQ '.template-repository // ""' "${CONFIG_FILE}")"
70+ if [[ -z "$TEMPLATE_REPO" ]]; then
71+ echo "::error::template-repository missing in ${CONFIG_FILE}"
6572 exit 1
6673 fi
6774 echo "template_repository=$TEMPLATE_REPO" >> $GITHUB_OUTPUT
68-
69- TEMPLATE_BRANCH=$($YQ_CMD '.template-branch // "main"' "${CONFIG_FILE}")
75+
76+ TEMPLATE_BRANCH=" $($YQ '.template-branch // "main"' "${CONFIG_FILE}")"
7077 echo "template_branch=$TEMPLATE_BRANCH" >> $GITHUB_OUTPUT
78+
79+ TEMPLATE_REF="$($YQ '.template-ref // ""' "${CONFIG_FILE}")"
80+ echo "template_ref=$TEMPLATE_REF" >> $GITHUB_OUTPUT
7181
72- # Read include and exclude patterns if present
73- INCLUDE=$($YQ_CMD '.include // ""' "${CONFIG_FILE}")
82+ # New: Tag/Ref override
83+ #TEMPLATE_REF_INPUT="${{ inputs.template-ref }}"
84+ #TEMPLATE_REF_CONFIG="$($YQ '.template-ref // ""' "${CONFIG_FILE}")"
85+ #TEMPLATE_REF="${TEMPLATE_REF_INPUT:-$TEMPLATE_REF_CONFIG}"
86+ #echo "template_ref=$TEMPLATE_REF" >> $GITHUB_OUTPUT
87+
88+ # Include patterns
89+ INCLUDE="$($YQ '.include // ""' "${CONFIG_FILE}")"
7490 echo "include<<EOF" >> $GITHUB_OUTPUT
7591 echo "$INCLUDE" >> $GITHUB_OUTPUT
7692 echo "EOF" >> $GITHUB_OUTPUT
77-
78- EXCLUDE=$($YQ_CMD '.exclude // ""' "${CONFIG_FILE}")
93+
94+ # Exclude patterns
95+ EXCLUDE="$($YQ '.exclude // ""' "${CONFIG_FILE}")"
7996 echo "exclude<<EOF" >> $GITHUB_OUTPUT
8097 echo "$EXCLUDE" >> $GITHUB_OUTPUT
8198 echo "EOF" >> $GITHUB_OUTPUT
8299
100+ # ------------------------------------------------------------
101+ # Sparse checkout template (branch or tag -> ref)
102+ # ------------------------------------------------------------
83103 - name : Sparse checkout template
84104 uses : actions/checkout@v6
85105 with :
86106 repository : ${{ steps.config.outputs.template_repository }}
87- ref : ${{ steps.config.outputs.template_branch }}
107+ ref : ${{ steps.config.outputs.template_ref || steps.config.outputs. template_branch }}
88108 path : .template-temp
109+ token : ${{ inputs.token }}
110+ fetch-depth : 0
89111 sparse-checkout : ${{ steps.config.outputs.include }}
90112 sparse-checkout-cone-mode : false
91- fetch-depth : 0
92- token : ${{ inputs.token }}
93- # persist-credentials: 'false'
94113
114+ # ------------------------------------------------------------
115+ # Clean template and apply excludes
116+ # ------------------------------------------------------------
95117 - name : Clean template and apply excludes
96118 shell : bash
97119 working-directory : .template-temp
98120 run : |
99121 rm -rf .git
100- if [[ -n "${{ steps.config.outputs.exclude }}" ]]; then
101- while IFS= read -r item; do
122+ EXCLUDES="${{ steps.config.outputs.exclude }}"
123+
124+ if [[ -n "$EXCLUDES" ]]; then
125+ echo "$EXCLUDES" | while IFS= read -r item; do
126+ [[ -z "$item" ]] && continue
102127 item="$(echo "$item" | xargs)"
103- [ -z "$item" ] || rm -rf "$item" 2>/dev/null || true
104- done <<< "${{ steps.config.outputs.exclude }}"
128+ rm -rf "$item" 2>/dev/null || true
129+ done
105130 fi
131+
106132 tree -L 2 || ls -R
107133
134+ # ------------------------------------------------------------
135+ # Apply template + commit & push
136+ # ------------------------------------------------------------
108137 - name : Commit and optionally push changes
109138 id : commit-changes
110139 shell : bash
111140 env :
112- GITHUB_TOKEN : ${{ inputs.token }}
113141 TEST_MODE : ${{ inputs.test-mode }}
114142 run : |
115143 cp -R .template-temp/. .
116144 rm -rf .template-temp
117145
118146 git add -A
119- git status
147+
120148 if git diff --cached --quiet; then
121- echo "✅ No changes to commit"
122149 echo "changes_detected=false" >> $GITHUB_OUTPUT
150+ echo "No changes."
123151 exit 0
124152 fi
125-
153+
126154 echo "changes_detected=true" >> $GITHUB_OUTPUT
127155
128- # Warn if workflow files are modified
129- if git diff --cached --name-only | grep -q "^\.github/workflows/"; then
130- echo "⚠️ Workflow files detected. Use PAT with 'workflow' scope."
156+ if git diff --cached --name-only | grep -q '^\.github/workflows/'; then
157+ echo "⚠️ Workflow files modified — PAT with workflow scope required."
131158 fi
132159
133- git config user.name " github-actions[bot]"
134- git config user.email " 41898282+github-actions[bot]@users.noreply.github.com"
160+ git config user.name ' github-actions[bot]'
161+ git config user.email ' 41898282+github-actions[bot]@users.noreply.github.com'
135162 git commit -m "${{ inputs.commit-message }}"
136163
137- # Configure remote with token
138- # git remote set-url origin "https://x-access-token:${{ inputs.token }}@github.com/${{ github.repository }}.git"
139-
140- echo "✅ Remote after reset (masked):"
141- git remote -v | sed -E 's@(https://)[^@]+@\\1****@g'
142-
143- echo "🔁 Testing ls-remote with this token..."
144- git ls-remote --heads origin || echo "❌ ls-remote failed"
145-
146- if [[ "${TEST_MODE}" == "true" ]]; then
147- echo "🧪 Test mode: skipping push and PR creation"
148- else
149- echo "🚀 Pushing changes to branch '${{ inputs.branch }}'..."
150- if git push origin "HEAD:${{ inputs.branch }}" --force-with-lease; then
151- echo "✅ Sync complete"
152- else
153- echo "⚠️ Push failed. Check permissions."
154- exit 1
155- fi
164+ if [[ "$TEST_MODE" == "true" ]]; then
165+ echo "🧪 Test mode: skipping push"
166+ exit 0
156167 fi
157168
158- - name : Create Pull Request (if not in test mode and there are changes)
169+ target_branch="${{ inputs.branch }}"
170+ git push origin "HEAD:$target_branch" --force-with-lease
171+
172+ # ------------------------------------------------------------
173+ # Create Pull Request
174+ # ------------------------------------------------------------
175+ - name : Create Pull Request
159176 id : create-pr
160177 if : ${{ inputs.test-mode != 'true' && steps.commit-changes.outputs.changes_detected == 'true' }}
161178 uses : peter-evans/create-pull-request@v7
162179 with :
163180 token : ${{ inputs.token }}
164181 branch : ${{ inputs.branch }}
165182 commit-message : ${{ inputs.commit-message }}
166- title : " chore: sync template from ${{ steps.config.outputs.template_repository }}@${{ steps.config.outputs.template_branch }}"
183+ delete-branch : false
184+ title : " chore: sync template from ${{ steps.config.outputs.template_repository }}@${{ steps.config.outputs.template_ref || steps.config.outputs.template_branch }}"
167185 body : |
168- This PR updates configuration files from
169- [${{ steps.config.outputs.template_repository }}@${{ steps.config.outputs.template_branch }}](https://github.com/${{ steps.config.outputs.template_repository }}/tree/${{ steps.config.outputs.template_branch }}).
170- delete-branch : true
186+ This PR syncs the template from:
187+ **${{ steps.config.outputs.template_repository }} @ ${{ steps.config.outputs.template_ref || steps.config.outputs.template_branch }}**
171188
189+ # ------------------------------------------------------------
190+ # Auto-merge
191+ # ------------------------------------------------------------
172192 - name : Enable auto-merge
193+ if : ${{ inputs.automerge == 'true' && steps.create-pr.outputs.pull-request-number }}
173194 shell : bash
174- if : ${{ inputs.automerge == 'true' && steps.create-pr.outputs.pull-request-number != '' }}
175195 env :
176196 GH_TOKEN : ${{ inputs.token }}
177197 run : |
0 commit comments