Auto-update Mailpit versions #387
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |