Add GitHub Releases notification step and release-note generation (#35)

* Add GitHub release notification workflow Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(workflow): Address Copilot review comments on PR #35 - Fix mtime-based release file selection: use needs.analyze.outputs.summary_file instead of 'ls -t' to avoid picking wrong file when artifacts get extracted with different mtimes - Add pages concurrency group to deploy job: prevent race conditions with deploy-site.yml workflow by sharing the same 'pages' concurrency group Resolves Copilot review comments ID:3258686126 and ID:3258686164 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot <copilot@github.com>

Juan Manuel Servera committed May 18, 2026 at 14:09 UTC 70aaaf25a5b2eb50e5e46ef030a5ea5a2b0fffb3
1 file changed +180
.github/workflows/crawl-and-publish.yml
+180
@@ -135,9 +135,14 @@ jobs:
135 needs: crawl
136 runs-on: ubuntu-latest
137 permissions:
138 + actions: read
139 contents: write
140 copilot-requests: write
141 models: read
142 + outputs:
143 + week: ${{ steps.analysis-context.outputs.week }}
144 + summary_file: ${{ steps.analysis-context.outputs.output_file }}
145 + current_datetime: ${{ steps.analysis-context.outputs.current_datetime }}
146
147 steps:
148 - name: Check out repository
@@ -272,3 +277,178 @@ jobs:
277 name: analyzed-data
278 path: data/analyzed/
279 if-no-files-found: warn
280 +
281 + generate:
282 + needs: analyze
283 + runs-on: ubuntu-latest
284 + permissions:
285 + actions: read
286 + contents: write
287 + outputs:
288 + page_path: ${{ steps.generate-content.outputs.page_path }}
289 +
290 + steps:
291 + - name: Check out repository
292 + uses: actions/checkout@v4
293 + with:
294 + fetch-depth: 0
295 + ref: ${{ github.event.repository.default_branch }}
296 +
297 + - name: Download analyzed data artifact
298 + uses: actions/download-artifact@v4
299 + with:
300 + name: analyzed-data
301 + path: data/analyzed/
302 +
303 + - name: Set up Python
304 + uses: actions/setup-python@v5
305 + with:
306 + python-version: '3.12'
307 +
308 + - name: Generate weekly content
309 + id: generate-content
310 + env:
311 + SUMMARY_FILE: ${{ needs.analyze.outputs.summary_file }}
312 + run: |
313 + set -euo pipefail
314 + python3 - <<'PY2' "$SUMMARY_FILE" >> "$GITHUB_OUTPUT"
315 + import sys
316 + from pathlib import Path
317 +
318 + import scripts.generate_content as generate_content
319 +
320 + summary_path = Path(sys.argv[1])
321 + page_path = generate_content.generate_content(summary_path)
322 + print(f"page_path={page_path.as_posix()}")
323 + PY2
324 +
325 + - name: Commit generated content
326 + env:
327 + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
328 + WEEK: ${{ needs.analyze.outputs.week }}
329 + run: |
330 + git config user.name "github-actions[bot]"
331 + git config user.email "github-actions[bot]@users.noreply.github.com"
332 + if ! git status --short -- content/weekly | grep -q .; then
333 + echo "No generated content changes to commit."
334 + exit 0
335 + fi
336 + git stash push --include-untracked --message generated-content -- content/weekly
337 + git fetch origin "$DEFAULT_BRANCH"
338 + git checkout -B "$DEFAULT_BRANCH" "origin/$DEFAULT_BRANCH"
339 + git stash pop || {
340 + echo "Failed to reapply generated content after syncing $DEFAULT_BRANCH."
341 + exit 1
342 + }
343 + git add content/weekly/
344 + git diff --cached --quiet || git commit -m "content: weekly page $WEEK"
345 + git push origin "HEAD:$DEFAULT_BRANCH" || {
346 + echo "Push failed after syncing with $DEFAULT_BRANCH."
347 + exit 1
348 + }
349 +
350 + - name: Upload generated content artifact
351 + uses: actions/upload-artifact@v4
352 + with:
353 + name: generated-content
354 + path: content/weekly/
355 + if-no-files-found: warn
356 +
357 + deploy:
358 + needs: generate
359 + runs-on: ubuntu-latest
360 + permissions:
361 + actions: read
362 + contents: read
363 + pages: write
364 + id-token: write
365 + concurrency:
366 + group: pages
367 + cancel-in-progress: true
368 + environment:
369 + name: github-pages
370 + url: ${{ steps.deployment.outputs.page_url }}
371 + env:
372 + HUGO_VERSION: 0.161.1
373 +
374 + steps:
375 + - name: Check out repository
376 + uses: actions/checkout@v4
377 + with:
378 + submodules: recursive
379 + fetch-depth: 0
380 + ref: ${{ github.event.repository.default_branch }}
381 +
382 + - name: Download raw crawl artifact
383 + uses: actions/download-artifact@v4
384 + with:
385 + name: raw-data
386 + path: data/raw/
387 +
388 + - name: Download analyzed data artifact
389 + uses: actions/download-artifact@v4
390 + with:
391 + name: analyzed-data
392 + path: data/analyzed/
393 +
394 + - name: Download generated content artifact
395 + uses: actions/download-artifact@v4
396 + with:
397 + name: generated-content
398 + path: content/weekly/
399 +
400 + - name: Configure GitHub Pages
401 + uses: actions/configure-pages@v5
402 +
403 + - name: Install Hugo
404 + run: |
405 + set -euo pipefail
406 + TARBALL="hugo_extended_${HUGO_VERSION}_linux-amd64.tar.gz"
407 + curl -sLJO "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/${TARBALL}"
408 + curl -sLJO "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_checksums.txt"
409 + sha256sum --check "hugo_${HUGO_VERSION}_checksums.txt" --ignore-missing
410 + rm "hugo_${HUGO_VERSION}_checksums.txt"
411 + mkdir -p "${HOME}/.local/hugo"
412 + tar -C "${HOME}/.local/hugo" -xf "${TARBALL}"
413 + rm "${TARBALL}"
414 + echo "${HOME}/.local/hugo" >> "${GITHUB_PATH}"
415 + export PATH="${HOME}/.local/hugo:${PATH}"
416 + hugo version
417 +
418 + - name: Build site
419 + run: hugo --minify
420 +
421 + - name: Upload Pages artifact
422 + uses: actions/upload-pages-artifact@v3
423 + with:
424 + path: ./public
425 +
426 + - name: Deploy to GitHub Pages
427 + id: deployment
428 + uses: actions/deploy-pages@v4
429 +
430 + notify:
431 + needs: [generate, deploy]
432 + runs-on: ubuntu-latest
433 + permissions:
434 + contents: write
435 +
436 + steps:
437 + - uses: actions/checkout@v4
438 +
439 + - uses: actions/download-artifact@v4
440 + with:
441 + name: analyzed-data
442 + path: data/analyzed/
443 +
444 + - name: Create GitHub Release
445 + env:
446 + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
447 + SUMMARY_FILE: ${{ needs.analyze.outputs.summary_file }}
448 + run: |
449 + WEEK=$(basename "$SUMMARY_FILE" | sed 's/-summary.md//')
450 +
451 + gh release create "week-${WEEK}" \
452 + --title "Week ${WEEK} — Tech Trends Summary" \
453 + --notes-file "$SUMMARY_FILE" \
454 + --latest