Skip to content

Merge pull request #47 from cosmos/update-concepts #6

Merge pull request #47 from cosmos/update-concepts

Merge pull request #47 from cosmos/update-concepts #6

# .github/workflows/sync-evm-changelog.yml
name: Sync EVM Changelog to Docs
on:
repository_dispatch:
types: [evm-release]
workflow_dispatch:
inputs:
release_tag:
description: 'EVM release tag to sync'
required: true
type: string
jobs:
sync-changelog:
runs-on: ubuntu-latest
steps:
- name: Checkout docs repo
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
- name: Fetch EVM changelog
id: fetch-changelog
run: |
# Get the release tag from either repository_dispatch or workflow_dispatch
if [[ "${{ github.event_name }}" == "repository_dispatch" ]]; then
RELEASE_TAG="${{ github.event.client_payload.tag_name }}"
else
RELEASE_TAG="${{ github.event.inputs.release_tag }}"
fi
echo "release_tag=$RELEASE_TAG" >> $GITHUB_OUTPUT
# Fetch the entire CHANGELOG.md from the EVM repo main branch
# We always pull from main to get the complete changelog
curl -s "https://raw.githubusercontent.com/cosmos/evm/main/CHANGELOG.md" > /tmp/changelog.md
if [ ! -s /tmp/changelog.md ]; then
echo "Failed to fetch changelog or changelog is empty"
exit 1
fi
echo "Successfully fetched changelog ($(wc -l < /tmp/changelog.md) lines)"
- name: Parse and convert changelog
id: convert
run: |
cat << 'EOF' > parse_changelog.js
const fs = require('fs');
function parseFullChangelog(content) {
const lines = content.split('\n');
const versions = [];
let currentVersion = null;
let currentDate = null;
let currentCategory = null;
let categories = {};
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
const trimmedLine = line.trim();
// Match version headers like "## [v0.3.1] - 2024-10-11" or "## v0.3.1 - 2024-10-11"
const versionMatch = trimmedLine.match(/^##\s+\[?(v[\d\.\-\w]+)\]?\s*(?:-\s*(.+))?$/);
if (versionMatch) {
// Save previous version if exists
if (currentVersion && Object.keys(categories).length > 0) {
versions.push({
version: currentVersion,
date: currentDate || new Date().toISOString().split('T')[0],
categories: { ...categories }
});
}
// Start new version
currentVersion = versionMatch[1];
currentDate = versionMatch[2] || null;
// Try to extract date if it's in format "2024-10-11" or similar
if (currentDate) {
const dateMatch = currentDate.match(/(\d{4}-\d{2}-\d{2})/);
if (dateMatch) {
currentDate = dateMatch[1];
}
}
categories = {};
currentCategory = null;
continue;
}
// Skip UNRELEASED section
if (trimmedLine === '## UNRELEASED') {
// Save previous version before skipping
if (currentVersion && Object.keys(categories).length > 0) {
versions.push({
version: currentVersion,
date: currentDate || new Date().toISOString().split('T')[0],
categories: { ...categories }
});
}
currentVersion = null;
categories = {};
currentCategory = null;
continue;
}
// Match category headers (### FEATURES, ### BUG FIXES, etc.)
if (currentVersion && trimmedLine.startsWith('### ')) {
currentCategory = trimmedLine.replace('### ', '').trim();
if (!categories[currentCategory]) {
categories[currentCategory] = [];
}
continue;
}
// Collect items under categories
if (currentVersion && currentCategory && trimmedLine && !trimmedLine.startsWith('#')) {
// Skip separator lines and empty content
if (trimmedLine !== '---' && trimmedLine !== '___' && trimmedLine !== '***') {
categories[currentCategory].push(trimmedLine);
}
}
}
// Save last version if exists
if (currentVersion && Object.keys(categories).length > 0) {
versions.push({
version: currentVersion,
date: currentDate || new Date().toISOString().split('T')[0],
categories: { ...categories }
});
}
return versions;
}
function convertToMintlify(versions) {
let mdxContent = `---
title: "Changelog"
description: "Follows the \\\`CHANGELOG.md\\\` for \\\`cosmos/evm\\\`"

Check failure on line 148 in .github/workflows/sync-evm-changelog.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/sync-evm-changelog.yml

Invalid workflow file

You have an error in your yaml syntax on line 148
---
# Changelog
This page tracks all releases and changes to the Cosmos EVM module.
`;
// Define the order we want to display categories
const categoryOrder = [
'FEATURES',
'IMPROVEMENTS',
'BUG FIXES',
'DEPENDENCIES',
'STATE BREAKING',
'API BREAKING',
'API-Breaking'
];
// Process each version
versions.forEach(({ version, date, categories }) => {
let updateContent = '';
// Process categories in preferred order
categoryOrder.forEach(category => {
const matchingCategory = Object.keys(categories).find(
cat => cat.toUpperCase().replace(/[-_]/g, ' ') === category.replace(/[-_]/g, ' ')
);
if (matchingCategory && categories[matchingCategory].length > 0) {
// Format category title
const formattedCategory = category
.toLowerCase()
.replace(/[-_]/g, ' ')
.replace(/\b\w/g, l => l.toUpperCase());
updateContent += `## ${formattedCategory}\n\n`;
categories[matchingCategory].forEach(item => {
if (item.trim()) {
// Clean up bullet points and ensure consistent formatting
let cleanItem = item
.replace(/^[\-\*]\s*/, '') // Remove existing bullet
.replace(/\\\[/g, '[') // Fix escaped brackets
.replace(/\\\]/g, ']');
updateContent += `* ${cleanItem}\n`;
}
});
updateContent += '\n';
}
});
// Add any remaining categories not in our predefined order
Object.keys(categories).forEach(category => {
const normalizedCategory = category.toUpperCase().replace(/[-_]/g, ' ');
const isProcessed = categoryOrder.some(
ordered => ordered.replace(/[-_]/g, ' ') === normalizedCategory
);
if (!isProcessed && categories[category].length > 0) {
const formattedCategory = category
.toLowerCase()
.replace(/[-_]/g, ' ')
.replace(/\b\w/g, l => l.toUpperCase());
updateContent += `## ${formattedCategory}\n\n`;
categories[category].forEach(item => {
if (item.trim()) {
let cleanItem = item
.replace(/^[\-\*]\s*/, '')
.replace(/\\\[/g, '[')
.replace(/\\\]/g, ']');
updateContent += `* ${cleanItem}\n`;
}
});
updateContent += '\n';
}
});
// Only add the Update component if there's content
if (updateContent.trim()) {
mdxContent += `<Update label="${date}" description="${version}" tags={["EVM", "Release"]}>
${updateContent.trim()}
</Update>
`;
}
});
return mdxContent;
}
// Main execution
try {
const changelogContent = fs.readFileSync('/tmp/changelog.md', 'utf8');
const versions = parseFullChangelog(changelogContent);
console.log(`Parsed ${versions.length} versions from changelog`);
if (versions.length === 0) {
console.error('No versions found in changelog');
process.exit(1);
}
const mintlifyContent = convertToMintlify(versions);
fs.writeFileSync('/tmp/release-notes.mdx', mintlifyContent);
console.log('Successfully converted changelog to Mintlify format');
} catch (error) {
console.error('Error:', error.message);
process.exit(1);
}
EOF
node parse_changelog.js
- name: Update changelog file
run: |
CHANGELOG_FILE="docs/changelog/release-notes.mdx"
# Create directory if it doesn't exist
mkdir -p "$(dirname "$CHANGELOG_FILE")"
# Replace the entire file with the newly generated content
cp /tmp/release-notes.mdx "$CHANGELOG_FILE"
echo "Changelog updated with $(grep -c '<Update' "$CHANGELOG_FILE") versions"
- name: Commit and push changes
run: |
git config --local user.email "[email protected]"
git config --local user.name "GitHub Action"
git add docs/changelog/release-notes.mdx
if git diff --staged --quiet; then
echo "No changes to commit"
else
git commit -m "docs: update EVM changelog for ${{ steps.fetch-changelog.outputs.release_tag }}"
git push
fi