Skip to content

Auto-update Mailpit versions #388

Auto-update Mailpit versions

Auto-update Mailpit versions #388

name: Auto-update Mailpit versions
on:
schedule:
# Run daily at 3 AM UTC
- cron: '0 3 * * *'
workflow_dispatch: # Allow manual triggering
jobs:
check-and-update:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v7
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '20'
- name: Check for new Mailpit versions
id: check-versions
run: |
# Get latest minor versions from Docker Hub (no patch versions)
echo "Fetching Mailpit versions from Docker Hub..."
AVAILABLE_VERSIONS=$(curl -s "https://registry.hub.docker.com/v2/repositories/axllent/mailpit/tags/?page_size=100" | \
jq -r '.results[].name' | \
grep -E '^v[0-9]+\.[0-9]+$' | \
sed 's/^v//' | \
sort -V)
echo "Available versions:"
echo "$AVAILABLE_VERSIONS"
# Get the latest version
LATEST_VERSION=$(echo "$AVAILABLE_VERSIONS" | tail -1)
echo "latest_version=$LATEST_VERSION" >> $GITHUB_OUTPUT
# Get current default version from plugin
CURRENT_DEFAULT=$(grep -o "version: '[^']*'" builders/mailpit.js | cut -d"'" -f2)
echo "current_default=$CURRENT_DEFAULT" >> $GITHUB_OUTPUT
# Get current supported versions
CURRENT_SUPPORTED=$(awk '/supported: \[/,/\]/' builders/mailpit.js | grep -o "'[0-9.]*'" | tr -d "'" | tr '\n' ',' | sed 's/,$//')
echo "current_supported=$CURRENT_SUPPORTED" >> $GITHUB_OUTPUT
# Get current highest supported version (first in supported array)
CURRENT_HIGHEST=$(echo "$CURRENT_SUPPORTED" | cut -d',' -f1)
echo "current_highest=$CURRENT_HIGHEST" >> $GITHUB_OUTPUT
# Check if update is needed (new version available)
if [ "$LATEST_VERSION" != "$CURRENT_HIGHEST" ]; then
echo "needs_update=true" >> $GITHUB_OUTPUT
echo "Update needed:"
echo " Current highest supported: $CURRENT_HIGHEST -> $LATEST_VERSION"
echo " Current default: $CURRENT_DEFAULT"
else
echo "needs_update=false" >> $GITHUB_OUTPUT
echo "No update needed. Current highest supported version $CURRENT_HIGHEST is latest."
fi
- name: Update plugin files
if: steps.check-versions.outputs.needs_update == 'true'
run: |
LATEST_VERSION="${{ steps.check-versions.outputs.latest_version }}"
CURRENT_DEFAULT="${{ steps.check-versions.outputs.current_default }}"
CURRENT_HIGHEST="${{ steps.check-versions.outputs.current_highest }}"
CURRENT_SUPPORTED="${{ steps.check-versions.outputs.current_supported }}"
echo "Updating to version: $LATEST_VERSION"
# Update builders/mailpit.js — keep 6 in supported, overflow to legacy
node -e "
const fs = require('fs');
const filePath = 'builders/mailpit.js';
let content = fs.readFileSync(filePath, 'utf8');
const MAX_SUPPORTED = 6;
const latestVersion = '$LATEST_VERSION';
// Parse current supported versions
const currentSupported = '$CURRENT_SUPPORTED'.split(',').filter(v => v);
// Parse current legacy versions
const legacyMatch = content.match(/legacy: \[\s*([\s\S]*?)\s*\]/);
const currentLegacy = legacyMatch
? legacyMatch[1].split(',').map(l => l.trim().replace(/['\s]/g, '')).filter(v => v)
: [];
// Build new supported list
let allSupported = [...currentSupported];
if (!allSupported.includes(latestVersion)) {
allSupported.push(latestVersion);
}
// Sort newest first
const sortDesc = (a, b) => {
const ap = a.split('.').map(Number);
const bp = b.split('.').map(Number);
for (let i = 0; i < Math.max(ap.length, bp.length); i++) {
if ((bp[i] || 0) !== (ap[i] || 0)) return (bp[i] || 0) - (ap[i] || 0);
}
return 0;
};
allSupported.sort(sortDesc);
// Overflow oldest supported into legacy
const newSupported = allSupported.slice(0, MAX_SUPPORTED);
const demoted = allSupported.slice(MAX_SUPPORTED);
const newLegacy = [...new Set([...demoted, ...currentLegacy])].sort(sortDesc);
// Update default version
content = content.replace(
/version: '[^']*'/,
\"version: '\" + latestVersion + \"'\"
);
// Update supported array
const supportedStr = newSupported.map(v => \" '\" + v + \"',\").join('\n');
content = content.replace(
/supported: \[\s*[\s\S]*?\s*\]/,
'supported: [\n' + supportedStr + '\n ]'
);
// Update or insert legacy array
if (newLegacy.length > 0) {
const legacyStr = newLegacy.map(v => \" '\" + v + \"',\").join('\n');
if (legacyMatch) {
content = content.replace(
/legacy: \[\s*[\s\S]*?\s*\]/,
'legacy: [\n' + legacyStr + '\n ]'
);
} else {
// Insert legacy right after supported array closing bracket
content = content.replace(
/(supported: \[[\s\S]*?\]),/,
'\$1,\n legacy: [\n' + legacyStr + '\n ],'
);
}
}
fs.writeFileSync(filePath, content);
console.log('Supported:', newSupported.join(', '));
console.log('Legacy:', newLegacy.join(', ') || 'none');
"
# Update examples
find examples -name "*.yml" -exec sed -i "s/mailpit:$CURRENT_HIGHEST\([^0-9.]\|$\)/mailpit:$LATEST_VERSION\1/g" {} \;
echo "Updated examples"
# Update README.md
sed -i "s/mailpit:$CURRENT_HIGHEST\([^0-9.]\|$\)/mailpit:$LATEST_VERSION\1/g" README.md
echo "Updated README.md"
# Update docs version references
find docs -name "*.md" -exec sed -i "s/mailpit:$CURRENT_HIGHEST\([^0-9.]\|$\)/mailpit:$LATEST_VERSION\1/g" {} \;
echo "Updated docs"
# Update CHANGELOG.md
node -e "
const fs = require('fs');
const filePath = 'CHANGELOG.md';
let content = fs.readFileSync(filePath, 'utf8');
const latestVersion = '$LATEST_VERSION';
const supportEntry = '- Added Mailpit v' + latestVersion + ' support.';
const defaultEntry = '- Set default Mailpit version to v' + latestVersion + '.';
if (content.includes(supportEntry) && content.includes(defaultEntry)) {
console.log('Changelog entries already exist');
} else {
const unreleasedHeaderRegex = /(## {{ UNRELEASED_VERSION }}[^\n]*\n\n)/;
const match = content.match(unreleasedHeaderRegex);
if (match) {
const header = match[1];
const rest = content.substring(match.index + header.length);
const newEntries = supportEntry + '\n' + defaultEntry + '\n';
fs.writeFileSync(filePath, header + newEntries + rest);
console.log('Added changelog entries');
} else {
console.log('Could not find unreleased header in CHANGELOG.md');
}
}
"
echo "Updated CHANGELOG.md"
# Update supported versions list in docs/index.md
node -e "
const fs = require('fs');
const filePath = 'docs/index.md';
let content = fs.readFileSync(filePath, 'utf8');
const pluginContent = fs.readFileSync('builders/mailpit.js', 'utf8');
const latestVersion = '$LATEST_VERSION';
// Get supported versions
const supportedMatch = pluginContent.match(/supported: \[\s*([\s\S]*?)\s*\]/);
const supported = supportedMatch
? supportedMatch[1].split(',').map(l => l.trim().replace(/['\s]/g, '')).filter(v => v)
: [];
// Get legacy versions
const legacyMatch = pluginContent.match(/legacy: \[\s*([\s\S]*?)\s*\]/);
const legacy = legacyMatch
? legacyMatch[1].split(',').map(l => l.trim().replace(/['\s]/g, '')).filter(v => v)
: [];
// Build version list
const versionList = supported.map(v => {
const isDefault = v === latestVersion;
const bold = isDefault ? '**' : '';
return '- ' + bold + '[' + v + '](https://hub.docker.com/r/axllent/mailpit/)' + bold + (isDefault ? ' **(default)**' : '');
}).join('\n');
let legacySection = '';
if (legacy.length > 0) {
legacySection = '\n\n> #### Warning::Legacy Versions\n> The following versions still work but are no longer officially supported: ' + legacy.join(', ') + '. We recommend upgrading.';
}
const supportedSectionRegex = /## Supported versions[\s\S]*?(?=\n## |\n# |$)/;
if (content.match(supportedSectionRegex)) {
content = content.replace(
supportedSectionRegex,
'## Supported versions\n\n' + versionList + '\n- [custom](https://docs.lando.dev/services/lando-3.html#overrides)' + legacySection + '\n\n'
);
}
fs.writeFileSync(filePath, content);
console.log('Updated docs/index.md');
"
# Update test file default version
if [ -f "test/mailpit.spec.js" ]; then
sed -i "s/DEFAULT_MAILPIT_VERSION = '[^']*'/DEFAULT_MAILPIT_VERSION = '$LATEST_VERSION'/" test/mailpit.spec.js
echo "Updated test/mailpit.spec.js"
fi
- name: Create Pull Request
if: steps.check-versions.outputs.needs_update == 'true'
uses: peter-evans/create-pull-request@v8
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: |
Updated Mailpit to v${{ steps.check-versions.outputs.latest_version }}
- Updated default version from ${{ steps.check-versions.outputs.current_default }} to ${{ steps.check-versions.outputs.latest_version }}
- Updated supported versions (max 6, older moved to legacy)
- Updated examples and documentation
title: "Updated Mailpit to v${{ steps.check-versions.outputs.latest_version }}"
body: |
## Summary
- Updates Mailpit plugin to use the latest version v${{ steps.check-versions.outputs.latest_version }}
- Keeps the 6 most recent minor versions in supported, older ones move to legacy
- Updates examples, documentation, and tests
## Changes
- **Plugin**: Updated default version to v${{ steps.check-versions.outputs.latest_version }}
- **Plugin**: Updated supported/legacy version arrays
- **Examples**: Updated version references
- **Documentation**: Updated version references in README.md, docs/, and supported versions list
- **Tests**: Updated default version constant
- **Changelog**: Added entry documenting the version update
---
*This PR was automatically generated by GitHub Actions*
branch: auto-update-mailpit-v${{ steps.check-versions.outputs.latest_version }}
delete-branch: true