@@ -2,7 +2,7 @@ name: Build and Deploy WordPress Theme
22
33on :
44 push :
5- brances :
5+ branches :
66 - ' shewa'
77
88 workflow_dispatch :
1111 DRY_RUN : ' true'
1212
1313jobs :
14- # ────────────────────────────────────────────────────────────
15- # JOB 1 — Build
16- # ────────────────────────────────────────────────────────────
1714 build :
1815 name : ' Build Theme'
1916 runs-on : ubuntu-latest
@@ -24,19 +21,15 @@ jobs:
2421 zip_path : ${{ steps.meta.outputs.zip_path }}
2522
2623 steps :
27- # 1. Checkout code -------------------------------------------------
2824 - name : Checkout repository
2925 uses : actions/checkout@v4
3026 with :
31- fetch-depth : 0 # full history so git describe works
27+ fetch-depth : 0
3228
33- # 2. Extract version from style.css --------------------------------
3429 - name : Extract version from style.css
3530 id : meta
3631 shell : bash
3732 run : |
38- # Pull the "Version:" header from the WP theme file header block.
39- # e.g. Version: 1.4.2
4033 RAW=$(grep -m1 -E '^[[:space:]]*\*?[[:space:]]*Version[[:space:]]*:[[:space:]]*' style.css \
4134 | sed -E 's/.*Version[[:space:]]*:[[:space:]]*//' \
4235 | tr -d '[:space:]')
@@ -49,69 +42,58 @@ jobs:
4942 ZIP_NAME="tutorstarter-${RAW}.zip"
5043 ZIP_PATH="${GITHUB_WORKSPACE}/${ZIP_NAME}"
5144
52- echo "Detected theme version: ${RAW}"
53- echo "version=${RAW}" >> "$GITHUB_OUTPUT"
45+ echo "version=${RAW}" >> "$GITHUB_OUTPUT"
5446 echo "zip_name=${ZIP_NAME}" >> "$GITHUB_OUTPUT"
55- echo "zip_path=${ZIP_PATH}" >> "$GITHUB_OUTPUT"
47+ echo "zip_path=${ZIP_PATH}" >> "$GITHUB_OUTPUT"
5648
57- # 3. Install PHP & Composer ----------------------------------------
5849 - name : Set up PHP
5950 uses : shivammathur/setup-php@v2
6051 with :
6152 php-version : ' 8.0'
6253 tools : composer:v2
6354 coverage : none
6455
65- # 4. Install WP-CLI ------------------------------------------------
6656 - name : Install WP-CLI
67- shell : bash
6857 run : |
69- curl -sS -o /usr/local/bin/wp https://raw.githubusercontent. com/wp-cli/builds/gh-pages/phar/ wp-cli.phar
58+ curl -sS -o /usr/local/bin/wp https://github. com/wp-cli/wp-cli/releases/download/v2.13.0/ wp-cli-2.13.0 .phar
7059 chmod +x /usr/local/bin/wp
7160 wp --version --allow-root
7261
7362 - name : Install dist-archive command
74- shell : bash
75- run : composer require wp-cli/dist-archive-command:^2.0
63+ run : |
64+ composer global require wp-cli/dist-archive-command:^3.0
65+ echo "$HOME/.composer/vendor/bin" >> $GITHUB_PATH
7666
77- # 5. Set up Node.js ------------------------------------------------
7867 - name : Set up Node.js
7968 uses : actions/setup-node@v4
8069 with :
8170 node-version : ' 20'
8271 cache : ' npm'
8372
84- # 6. Install npm dependencies ----------------------------------------
8573 - name : Install npm dependencies
86- run : npm i
74+ run : npm ci
8775
88- # 7. Build theme assets ---------------------------------------------------
89- # Runs: composer i --no-dev && npm run production && npm run makepot && npm run bundle
9076 - name : Build theme assets
91- run : npm run build
77+ run :
78+ npm run build
79+ composer i --no-dev
80+ npm run production
81+ npm run makepot
9282 env :
9383 NODE_ENV : production
9484 NODE_OPTIONS : --openssl-legacy-provider
9585
96- # 6. Verify the zip was produced ------------------------------------
97- - name : Verify zip artifact
98- id : verify_zip
99- shell : bash
86+ - name : Build theme zip
10087 run : |
101- ZIP_NAME="${{ steps.meta.outputs.zip_name }}"
102- ZIP_PATH="${{ steps.meta.outputs.zip_path }}"
88+ wp dist-archive . "${{ steps.meta.outputs.zip_path }}" --allow-root
10389
104- if [[ ! -f "$ZIP_PATH" ]]; then
105- echo "::error::Expected zip not found at ${ZIP_PATH}"
106- echo "Files in workspace root:"
107- ls -lh "${GITHUB_WORKSPACE}"/*.zip 2>/dev/null || echo "(no zips found) "
90+ - name : Verify zip artifact
91+ run : |
92+ if [[ ! -f "${{ steps.meta.outputs.zip_path }}" ]]; then
93+ echo "::error::Zip not found"
10894 exit 1
10995 fi
11096
111- SIZE=$(du -sh "$ZIP_PATH" | cut -f1)
112- echo "✅ Found ${ZIP_NAME} (${SIZE})"
113-
114- # 7. Upload zip as workflow artifact so next jobs can use it --------
11597 - name : Upload build artifact
11698 uses : actions/upload-artifact@v4
11799 with :
@@ -120,224 +102,89 @@ jobs:
120102 retention-days : 1
121103 if-no-files-found : error
122104
123- # ────────────────────────────────────────────────────────────
124- # JOB 2 — Deploy to WordPress.org SVN
125- # Skipped entirely when dry_run == 'true'
126- # ────────────────────────────────────────────────────────────
127105 deploy-wporg :
128106 name : ' Deploy to WordPress.org'
129107 runs-on : ubuntu-latest
130108 needs : build
131- if : ${{ github.event.inputs.dry_run != 'true' }}
109+ if : ${{ env.DRY_RUN != 'true' }}
132110
133111 env :
134- THEME_SLUG : tutorstarter # WP.org theme slug
112+ THEME_SLUG : tutorstarter
135113 THEME_VERSION : ${{ needs.build.outputs.version }}
136- ZIP_NAME : ${{ needs.build.outputs.zip_name }}
137- SVN_BASE : https://themes.svn.wordpress.org
114+ ZIP_NAME : ${{ needs.build.outputs.zip_name }}
115+ SVN_BASE : https://themes.svn.wordpress.org
138116
139117 steps :
140- # 1. Install SVN ----------------------------------------------------
141118 - name : Install Subversion
142119 run : |
143120 sudo apt-get update -q
144121 sudo apt-get install -y subversion
145122
146- # 2. Download the zip built in job 1 --------------------------------
147123 - name : Download build artifact
148124 uses : actions/download-artifact@v4
149125 with :
150126 name : theme-zip
151127 path : /tmp/build
152128
153- # 3. Checkout WP.org SVN (trunk only, no full history) --------------
154129 - name : Checkout SVN trunk
155- shell : bash
156130 run : |
157131 SVN_URL="${SVN_BASE}/${THEME_SLUG}"
158- echo "Checking out SVN: ${SVN_URL}"
159- svn checkout \
160- --depth immediates \
132+ svn checkout --depth immediates \
161133 --username "${{ secrets.WPORG_SVN_USERNAME }}" \
162134 --password "${{ secrets.WPORG_SVN_PASSWORD }}" \
163- --no-auth-cache \
164- --non-interactive \
135+ --no-auth-cache --non-interactive \
165136 "${SVN_URL}" /tmp/svn
166- # Deepen trunk for a full working copy
137+
167138 svn update /tmp/svn/trunk --set-depth infinity \
168139 --username "${{ secrets.WPORG_SVN_USERNAME }}" \
169140 --password "${{ secrets.WPORG_SVN_PASSWORD }}" \
170- --no-auth-cache \
171- --non-interactive
141+ --no-auth-cache --non-interactive
172142
173- # 4. Unzip theme into a staging directory ---------------------------
174143 - name : Unzip theme
175- shell : bash
176144 run : |
177- mkdir -p /tmp/theme-extracted
178- unzip -q "/tmp/build/${ZIP_NAME}" -d /tmp/theme-extracted
179-
180- # The zip may contain a sub-folder named after the theme; normalise.
181- INNER=$(ls /tmp/theme-extracted)
182- if [[ $(echo "$INNER" | wc -l) -eq 1 && -d "/tmp/theme-extracted/${INNER}" ]]; then
183- mv "/tmp/theme-extracted/${INNER}" /tmp/theme-files
184- else
185- mv /tmp/theme-extracted /tmp/theme-files
186- fi
145+ mkdir -p /tmp/theme-files
146+ unzip -q "/tmp/build/${ZIP_NAME}" -d /tmp/theme-files
187147
188- # 5. Sync files into SVN trunk -------------------------------------
189148 - name : Sync theme files to SVN trunk
190- shell : bash
191149 run : |
192150 TRUNK=/tmp/svn/trunk
193-
194- # Remove everything currently in trunk
195151 find "$TRUNK" -mindepth 1 -delete
196-
197- # Copy fresh build
198152 cp -r /tmp/theme-files/. "$TRUNK/"
199153
200- # Stage additions and deletions
201- svn status "$TRUNK" | grep '^?' | awk '{print $2}' | \
202- xargs -r svn add --force --no-auto-props
203- svn status "$TRUNK" | grep '^!' | awk '{print $2}' | \
204- xargs -r svn delete
205-
206- # 6. Create a versioned tag in SVN ----------------------------------
207- - name : Create SVN tag
208- shell : bash
209- run : |
210- TAGS_URL="${SVN_BASE}/${THEME_SLUG}/tags/${THEME_VERSION}"
211- TRUNK_URL="${SVN_BASE}/${THEME_SLUG}/trunk"
212-
213- # Check if tag already exists
214- if svn info "$TAGS_URL" \
215- --username "${{ secrets.WPORG_SVN_USERNAME }}" \
216- --password "${{ secrets.WPORG_SVN_PASSWORD }}" \
217- --no-auth-cache --non-interactive 2>/dev/null; then
218- echo "::warning::SVN tag ${THEME_VERSION} already exists — skipping tag creation."
219- else
220- svn copy "$TRUNK_URL" "$TAGS_URL" \
221- --username "${{ secrets.WPORG_SVN_USERNAME }}" \
222- --password "${{ secrets.WPORG_SVN_PASSWORD }}" \
223- --no-auth-cache \
224- --non-interactive \
225- -m "Tagging version ${THEME_VERSION}"
226- fi
154+ svn status "$TRUNK" | grep '^?' | awk '{print $2}' | xargs -r svn add --force
155+ svn status "$TRUNK" | grep '^!' | awk '{print $2}' | xargs -r svn delete
227156
228- # 7. Commit trunk ---------------------------------------------------
229157 - name : Commit to SVN trunk
230- shell : bash
231158 run : |
232159 svn commit /tmp/svn/trunk \
233160 --username "${{ secrets.WPORG_SVN_USERNAME }}" \
234161 --password "${{ secrets.WPORG_SVN_PASSWORD }}" \
235- --no-auth-cache \
236- --non-interactive \
162+ --no-auth-cache --non-interactive \
237163 -m "Deploy version ${THEME_VERSION}"
238164
239- # ────────────────────────────────────────────────────────────
240- # JOB 3 — Create GitHub Release
241- # Runs after build (and after deploy when not a dry-run)
242- # ────────────────────────────────────────────────────────────
243165 release :
244166 name : ' Create GitHub Release'
245167 runs-on : ubuntu-latest
246168 needs : [build, deploy-wporg]
247- # Always run this job even if deploy-wporg was skipped (dry-run case)
248169 if : always() && needs.build.result == 'success'
249170
250171 env :
251172 VERSION : ${{ needs.build.outputs.version }}
252173 ZIP_NAME : ${{ needs.build.outputs.zip_name }}
253- IS_DRY : ${{ github.event.inputs.dry_run || 'false' }}
254174
255175 steps :
256- # 1. Download the zip -----------------------------------------------
257176 - name : Download build artifact
258177 uses : actions/download-artifact@v4
259178 with :
260179 name : theme-zip
261180 path : /tmp/release
262181
263- # 2. Resolve the Git tag name ---------------------------------------
264- # For tag-push events: use the pushed tag.
265- # For manual (workflow_dispatch) runs: derive from version.
266- - name : Resolve release tag
267- id : tag
268- shell : bash
269- run : |
270- if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
271- TAG_NAME="${GITHUB_REF_NAME}"
272- else
273- TAG_NAME="v${VERSION}"
274- fi
275- echo "tag_name=${TAG_NAME}" >> "$GITHUB_OUTPUT"
276-
277- # 3. Build release notes --------------------------------------------
278- - name : Build release notes
279- id : notes
280- shell : bash
281- run : |
282- DRY_LABEL=""
283- if [[ "${IS_DRY}" == "true" ]]; then
284- DRY_LABEL=" [DRY RUN — WP.org deploy skipped]"
285- fi
286-
287- NOTES=$(cat <<EOF
288- ## TutorStarter ${VERSION}${DRY_LABEL}
289-
290- **Theme Version:** \`${VERSION}\`
291- **Build triggered by:** \`${GITHUB_ACTOR}\`
292- **Workflow run:** [#${GITHUB_RUN_NUMBER}](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID})
293-
294- ### Installation
295- Download \`${ZIP_NAME}\` below and upload it via **Appearance → Themes → Add New → Upload Theme** in your WordPress dashboard.
296- EOF
297- )
298-
299- # Write to a file to avoid shell-escaping issues in later steps
300- echo "$NOTES" > /tmp/release_notes.md
301- echo "notes_file=/tmp/release_notes.md" >> "$GITHUB_OUTPUT"
302-
303- # 4. Create (or update) the GitHub release -------------------------
304182 - name : Create GitHub Release
305- shell : bash
306183 env :
307184 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
308185 run : |
309- TAG="${{ steps.tag.outputs.tag_name }}"
310- ASSET="/tmp/release/${ZIP_NAME}"
311- NOTES_FILE="${{ steps.notes.outputs.notes_file }}"
312-
313- # Create or overwrite an existing draft/release for this tag
186+ TAG="v${VERSION}"
314187 gh release create "$TAG" \
315- --repo "${GITHUB_REPOSITORY}" \
316188 --title "TutorStarter ${VERSION}" \
317- --notes-file "$NOTES_FILE" \
318- --draft=false \
319- --latest \
320- "$ASSET" \
321- || gh release upload "$TAG" "$ASSET" \
322- --repo "${GITHUB_REPOSITORY}" \
323- --clobber
324-
325- echo "✅ GitHub release ${TAG} created/updated."
326-
327- # 5. Print summary to Actions UI ------------------------------------
328- - name : Write job summary
329- shell : bash
330- run : |
331- echo "## 🚀 Build & Deploy Summary" >> "$GITHUB_STEP_SUMMARY"
332- echo "" >> "$GITHUB_STEP_SUMMARY"
333- echo "| Field | Value |" >> "$GITHUB_STEP_SUMMARY"
334- echo "|---|---|" >> "$GITHUB_STEP_SUMMARY"
335- echo "| Theme version | \`${VERSION}\` |" >> "$GITHUB_STEP_SUMMARY"
336- echo "| Zip artifact | \`${ZIP_NAME}\` |" >> "$GITHUB_STEP_SUMMARY"
337- echo "| Git tag | \`${{ steps.tag.outputs.tag_name }}\` |" >> "$GITHUB_STEP_SUMMARY"
338- if [[ "${IS_DRY}" == "true" ]]; then
339- echo "| WP.org deploy | ⏭️ **Skipped (dry run)** |" >> "$GITHUB_STEP_SUMMARY"
340- else
341- echo "| WP.org deploy | ✅ Completed |" >> "$GITHUB_STEP_SUMMARY"
342- fi
343- echo "| GitHub release | ✅ Published |" >> "$GITHUB_STEP_SUMMARY"
189+ "/tmp/release/${ZIP_NAME}" \
190+ || gh release upload "$TAG" "/tmp/release/${ZIP_NAME}" --clobber
0 commit comments