-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
configurationProject setup and configuration filesProject setup and configuration filesdependenciesDependency updatesDependency updatesgithub_actionsGitHub .github/ folder configurationGitHub .github/ folder configuration
Milestone
Description
ci(github-actions): update update-node-npm.yml workflow to use PR template file
| ⏱️ Estimate | 📊 Priority | 📏 Size | 📅 Start | 📅 End |
|---|---|---|---|---|
| 4h | P2 | M | 05-02-2026 | 05-02-2026 |
📸 Screenshots
| Current | Expected |
|---|---|
| N/A — This change has no visual impact. | N/A — This change has no visual impact. |
📝 Summary
- The
update-node-npm.ymlworkflow generates PRs with an outdated body format - Extract the PR body to a template file
.github/WORKFLOW_TEMPLATE/pr-node-npm.mdwith placeholders - Update the workflow to read the template, replace placeholders and generate the PR body
- Includes improvements to the job summary output
💡 Why this change?
- The PR body is currently built inline as a YAML multiline string, making it hard to read and maintain
- A separate template file is easier to edit, review and version control
- The current format uses outdated headers (
⏱️ Time,📅 Date,🔧 Build Type,📝 Description) - Missing sections:
📸 Screenshots,📌 Notes, structured🔗 References - Tests should not be pre-checked
[x]since the workflow does not verify them - Branch name uses
dependabot/prefix which is misleading - The
Changes Madesection should useUpdate/Keeplogic based on actual changes
📋 Steps
Phase 1: Create PR template file
- Create
.github/WORKFLOW_TEMPLATE/pr-node-npm.mdwith placeholders
# build(deps): update `node@{{LATEST_NODE}}` and `npm@{{LATEST_NPM}}` versions
| ⏱️ Estimate | 📊 Priority | 📏 Size | 📅 Start | 📅 End |
|---------|-------------|---------|----------|--------|
| 2h | P2 | XS | {{DATE}} | {{DATE}} |
## 📸 Screenshots
| Before | After |
|:------:|:-----:|
| N/A — This change has no visual impact. | N/A — This change has no visual impact. |
## 🔄 Type of Change
- [ ] Bug fix
- [ ] Breaking change
- [x] Dependency
- [ ] New feature
- [ ] Improvement
- [x] Configuration
- [ ] Documentation
- [x] CI/CD
## 📝 Summary
- Automatic update of `node` and `npm` versions detected by the `update-node-npm.yml` workflow
- Runs monthly (first Saturday) or manually via `workflow_dispatch`
- Checks for new Node.js LTS versions and creates this PR to update the project configuration files
- Updates `package.json` `engines` (`node` and `npm`) to the bundled versions
- If `.noderc.json` exists with `maxMajorVersion`, updates only within that major version
## 📋 Changes Made
{{CHANGES_MADE}}
## 🧪 Tests
- [ ] Verify `node -v` matches the updated version in `.nvmrc`
- [ ] Verify `npm -v` matches the updated version in `package.json` `engines.npm`
- [ ] Run `npm install` without errors
- [ ] Run `npm run build` without errors
- [ ] Run `npm run dev` and check the app loads correctly
- [ ] Check CI workflows pass on the PR branch
## 📌 Notes
Version changes:
| File | Configuration | From | To | Type |
|------|---------------|------|-----|------|
{{NOTES_TABLE}}
## 🔗 References
### Files to modify
- `.nvmrc`
- `package.json`
- `.github/workflows/check-node.yml`
### Documentation
- [Node.js — Release schedule](https://nodejs.org/en/about/releases/)
- [Node.js — Changelog](https://github.com/nodejs/node/blob/main/CHANGELOG.md)
- [NPM CLI — Releases](https://github.com/npm/cli/releases)
- [NVM — Node Version Manager](https://github.com/nvm-sh/nvm)
- [GitHub Actions — `setup-node` matrix testing](https://github.com/actions/setup-node?tab=readme-ov-file#matrix-testing)
### Related Files
- `.github/workflows/update-node-npm.yml`Phase 2: Add change detection step
- Add step after
🔄 Check if update is neededto detect change types and version types
- name: 🔍 Detect change types
if: steps.check-update.outputs.update_needed == 'true'
id: changes
run: |
get_change_type() {
local old=$1 new=$2
local old_major=$(echo "$old" | tr -d 'v[]' | cut -d. -f1 | tr -d ' ')
local old_minor=$(echo "$old" | tr -d 'v[]' | cut -d. -f2 | tr -d ' ')
local new_major=$(echo "$new" | tr -d 'v[]' | cut -d. -f1 | tr -d ' ')
local new_minor=$(echo "$new" | tr -d 'v[]' | cut -d. -f2 | tr -d ' ')
if [ "$old_major" != "$new_major" ]; then echo "🔴 Major"
elif [ "$old_minor" != "$new_minor" ]; then echo "🟡 Minor"
else echo "🟢 Patch"; fi
}
CURRENT_NODE="${{ steps.current-versions.outputs.current_node }}"
LATEST_NODE="${{ steps.node-versions.outputs.latest_version }}"
CURRENT_NPM="${{ steps.current-versions.outputs.current_npm }}"
LATEST_NPM="${{ steps.node-versions.outputs.npm_version }}"
CURRENT_MATRIX="${{ steps.current-versions.outputs.current_matrix }}"
NEW_MATRIX="${{ steps.node-versions.outputs.matrix }}"
echo "node_type=$(get_change_type "$CURRENT_NODE" "$LATEST_NODE")" >> $GITHUB_OUTPUT
if [ "$CURRENT_NPM" != "$LATEST_NPM" ]; then
echo "npm_changed=true" >> $GITHUB_OUTPUT
echo "npm_type=$(get_change_type "$CURRENT_NPM" "$LATEST_NPM")" >> $GITHUB_OUTPUT
else
echo "npm_changed=false" >> $GITHUB_OUTPUT
echo "npm_type=-" >> $GITHUB_OUTPUT
fi
if [ "$CURRENT_MATRIX" != "$NEW_MATRIX" ]; then
echo "matrix_changed=true" >> $GITHUB_OUTPUT
echo "matrix_type=🔴 Major" >> $GITHUB_OUTPUT
else
echo "matrix_changed=false" >> $GITHUB_OUTPUT
echo "matrix_type=-" >> $GITHUB_OUTPUT
fiPhase 3: Build PR body from template
- Add step to generate dynamic sections and replace placeholders in template
- name: 📄 Build PR body
if: steps.check-update.outputs.update_needed == 'true'
run: |
CURRENT_NODE="${{ steps.current-versions.outputs.current_node }}"
LATEST_NODE="${{ steps.node-versions.outputs.latest_version }}"
CURRENT_NPM="${{ steps.current-versions.outputs.current_npm }}"
LATEST_NPM="${{ steps.node-versions.outputs.npm_version }}"
CURRENT_MATRIX="${{ steps.current-versions.outputs.current_matrix }}"
NEW_MATRIX="${{ steps.node-versions.outputs.matrix }}"
DATE="${{ steps.check-update.outputs.date }}"
NODE_TYPE="${{ steps.changes.outputs.node_type }}"
NPM_TYPE="${{ steps.changes.outputs.npm_type }}"
MATRIX_TYPE="${{ steps.changes.outputs.matrix_type }}"
# Build Changes Made
CHANGES="- Update \`.nvmrc\` file: \`v${CURRENT_NODE}\` → \`v${LATEST_NODE}\`
"
CHANGES+="- Update \`package.json\` file in \`engines.node\`: \`${CURRENT_NODE}\` → \`${LATEST_NODE}\`
"
if [ "${{ steps.changes.outputs.npm_changed }}" == "true" ]; then
CHANGES+="- Update \`package.json\` file in \`engines.npm\`: \`${CURRENT_NPM}\` → \`${LATEST_NPM}\`
"
else
CHANGES+="- Keep \`package.json\` file in \`engines.npm\`: \`${CURRENT_NPM}\`
"
fi
if [ "${{ steps.changes.outputs.matrix_changed }}" == "true" ]; then
CHANGES+="- Update \`check-node.yml\` file in matrix: \`${CURRENT_MATRIX}\` → \`${NEW_MATRIX}\`"
else
CHANGES+="- Keep \`check-node.yml\` file in matrix: \`${CURRENT_MATRIX}\`"
fi
# Build Notes table rows
NOTES="| \`.nvmrc\` | Node version | \`v${CURRENT_NODE}\` | \`v${LATEST_NODE}\` | ${NODE_TYPE} |
"
NOTES+="| \`package.json\` | engines.node | \`${CURRENT_NODE}\` | \`${LATEST_NODE}\` | ${NODE_TYPE} |
"
if [ "${{ steps.changes.outputs.npm_changed }}" == "true" ]; then
NOTES+="| \`package.json\` | engines.npm | \`${CURRENT_NPM}\` | \`${LATEST_NPM}\` | ${NPM_TYPE} |
"
else
NOTES+="| \`package.json\` | engines.npm | \`${CURRENT_NPM}\` | \`-\` | \`-\` |
"
fi
if [ "${{ steps.changes.outputs.matrix_changed }}" == "true" ]; then
NOTES+="| \`check-node.yml\` | matrix | \`${CURRENT_MATRIX}\` | \`${NEW_MATRIX}\` | ${MATRIX_TYPE} |"
else
NOTES+="| \`check-node.yml\` | matrix | \`${CURRENT_MATRIX}\` | \`-\` | \`-\` |"
fi
# Write dynamic sections to temp files
echo -e "$CHANGES" > /tmp/changes.txt
echo -e "$NOTES" > /tmp/notes.txt
# Copy template and replace simple placeholders
cp .github/WORKFLOW_TEMPLATE/pr-node-npm.md pr-body.md
sed -i "s|{{LATEST_NODE}}|${LATEST_NODE}|g" pr-body.md
sed -i "s|{{LATEST_NPM}}|${LATEST_NPM}|g" pr-body.md
sed -i "s|{{DATE}}|${DATE}|g" pr-body.md
# Replace multi-line placeholders
awk '/{{CHANGES_MADE}}/{system("cat /tmp/changes.txt"); next}1' pr-body.md > pr-body.tmp && mv pr-body.tmp pr-body.md
awk '/{{NOTES_TABLE}}/{system("cat /tmp/notes.txt"); next}1' pr-body.md > pr-body.tmp && mv pr-body.tmp pr-body.mdPhase 4: Update create-pull-request step
- Update title, commit message, branch, labels and use
body-path
- name: 🚀 Create Pull Request
if: |
steps.check-update.outputs.update_needed == 'true' &&
(steps.current-versions.outputs.has_nvmrc == 'true' ||
steps.current-versions.outputs.has_engines == 'true' ||
steps.current-versions.outputs.has_node_yml == 'true')
id: create-pr
uses: peter-evans/create-pull-request@v8
with:
token: ${{ secrets.PAT_WORKFLOW }}
commit-message: "build(deps): update `node@${{ steps.node-versions.outputs.latest_version }}` and `npm@${{ steps.node-versions.outputs.npm_version }}` versions"
title: "build(deps): update `node@${{ steps.node-versions.outputs.latest_version }}` and `npm@${{ steps.node-versions.outputs.npm_version }}` versions"
body-path: pr-body.md
branch: update/node-${{ steps.node-versions.outputs.latest_version }}
delete-branch: true
labels: |
dependencies
github_actions
configuration
assignees: beatrizsmerinoPhase 5: Update job summary
- Replace the
📊 Summarystep with the new format
- name: 📊 Summary
run: |
if [ "${{ steps.check-update.outputs.update_needed }}" == "true" ]; then
STATUS_BADGE=""
else
STATUS_BADGE=""
fi
if [ "${{ steps.config.outputs.has_config }}" == "true" ]; then
LIMIT_BADGE=""
MAX_VALUE="\`${{ steps.config.outputs.max_major }}\`"
else
LIMIT_BADGE=""
MAX_VALUE="\`-\`"
fi
NODE_TYPE="${{ steps.changes.outputs.node_type }}"
NPM_TYPE="${{ steps.changes.outputs.npm_type }}"
MATRIX_TYPE="${{ steps.changes.outputs.matrix_type }}"
if [ "${{ steps.check-update.outputs.update_needed }}" != "true" ]; then
NODE_TYPE="-"; NPM_TYPE="-"; MATRIX_TYPE="-"
fi
NVMRC_STATUS=$( [ "${{ steps.current-versions.outputs.has_nvmrc }}" == "true" ] && echo "✅ Found" || echo "❌ Not found" )
ENGINES_STATUS=$( [ "${{ steps.current-versions.outputs.has_engines }}" == "true" ] && echo "✅ Found" || echo "❌ Not found" )
NODE_YML_STATUS=$( [ "${{ steps.current-versions.outputs.has_node_yml }}" == "true" ] && echo "✅ Found" || echo "❌ Not found" )
NODERC_STATUS=$( [ "${{ steps.config.outputs.has_config }}" == "true" ] && echo "✅ Found" || echo "❌ Not found" )
PR_URL="${{ steps.create-pr.outputs.pull-request-url }}"
PR_NUMBER="${{ steps.create-pr.outputs.pull-request-number }}"
if [ -n "$PR_URL" ]; then
PR_LINK="✅ [PR #${PR_NUMBER} — build(deps): update \`node@${{ steps.node-versions.outputs.latest_version }}\` and \`npm@${{ steps.node-versions.outputs.npm_version }}\` versions](${PR_URL})"
else
PR_LINK="ℹ️ No update needed — all versions are up to date."
fi
cat >> $GITHUB_STEP_SUMMARY << EOF
# Node.js Update Check Summary
${STATUS_BADGE} ${LIMIT_BADGE}
> 📅 Last check: $(date +%d-%m-%Y)
## 🔢 Version Comparison
| Package | Files | Max | Current | Latest | Type |
|---------|-------|:---:|:-------:|:------:|:----:|
| **Node** | \`.nvmrc\`, \`package.json\` | ${MAX_VALUE} | \`${{ steps.current-versions.outputs.current_node }}\` | \`${{ steps.node-versions.outputs.latest_version }}\` | ${NODE_TYPE} |
| **NPM** | \`package.json\` | \`-\` | \`${{ steps.current-versions.outputs.current_npm }}\` | \`${{ steps.node-versions.outputs.npm_version }}\` | ${NPM_TYPE} |
| **CI Matrix** | \`check-node.yml\` | \`-\` | \`${{ steps.current-versions.outputs.current_matrix }}\` | \`${{ steps.node-versions.outputs.matrix }}\` | ${MATRIX_TYPE} |
> **Max** is read from \`.noderc.json\` (\`maxMajorVersion\` field). If the file doesn't exist, updates to the latest LTS version.
## 📁 Project Files
| File | Status |
|------|:------:|
| \`.noderc.json\` | ${NODERC_STATUS} |
| \`.nvmrc\` | ${NVMRC_STATUS} |
| \`package.json\` | ${ENGINES_STATUS} |
| \`check-node.yml\` | ${NODE_YML_STATUS} |
## 🔗 Pull Request
${PR_LINK}
EOF🧪 Tests
- Trigger workflow manually with
workflow_dispatch - Verify PR is created with the new body format from template
- Verify PR title uses
build(deps):prefix - Verify PR branch uses
update/node-prefix instead ofdependabot/ - Verify PR labels include
dependencies,github_actionsandconfiguration - Verify
Changes Madesection usesUpdate/Keepcorrectly - Verify
Notestable shows correct version types (🟢 Patch / 🟡 Minor / 🔴 Major) - Verify job summary shows Version Comparison table with
TypeandMaxcolumns - Verify job summary shows PR link when created
- Verify job summary shows "No update needed" when up to date
🔗 References
Files to create
.github/WORKFLOW_TEMPLATE/pr-node-npm.md
Files to modify
.github/workflows/update-node-npm.yml
Related Issues
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
configurationProject setup and configuration filesProject setup and configuration filesdependenciesDependency updatesDependency updatesgithub_actionsGitHub .github/ folder configurationGitHub .github/ folder configuration