mega-linter-runner
Version:
Local runner for MegaLinter
271 lines (234 loc) • 12.3 kB
YAML
---
# =============================================================
# Check for New MegaLinter Version Workflow
#
# This workflow checks daily for new versions of the MegaLinter
# custom-builder action and creates a release if a new version is found.
#
# Usage:
# - Runs daily at 00:00 UTC via schedule
# - Can be manually triggered via workflow_dispatch
# - Compares MegaLinter tags with current repository tags
# - Creates a new release if a new MegaLinter version is detected
#
# The workflow will:
# 1. Fetch all tags from oxsecurity/megalinter repository
# 2. Fetch all tags from the current repository
# 3. Find new tags that exist in MegaLinter but not in current repo
# 4. Create a release with the new version tag
# 5. The release will trigger megalinter-custom-flavor-builder.yml
#
# Required permissions:
# - contents: write (to create releases and tags)
#
# Required repository secrets:
# - PAT_TOKEN: Personal Access Token with 'contents' and 'actions' permissions
# This is required to trigger the builder workflow. Without it, the workflow
# will fail and the release will be deleted (to be recreated once the token is set).
#
# SECURITY WARNING: Using a PAT comes with risk. Open-source projects have been
# heavily targeted by supply-chain attacks in recent months, and a leaked or
# compromised PAT can give attackers broad write access to your repository —
# better safe than sorry! If you do not need fully automatic daily version
# sync, you can skip the PAT entirely and trigger this workflow manually
# (Actions tab → "Check for New MegaLinter Version" → "Run workflow") whenever
# you want to bump to a new MegaLinter release. Only configure PAT_TOKEN if
# the daily automation is worth the trade-off, and always scope it to this
# single repository with the minimum required permissions.
#
# To create a Fine-grained PAT (still discouraged unless you need automation):
# 1. Go to GitHub Settings > Developer settings > Personal access tokens > Fine-grained tokens
# 2. Click "Generate new token"
# 3. Give it a descriptive name (e.g., "MegaLinter Auto-Release")
# 4. Set expiration (e.g., 90 days or 1 year)
# 5. Under "Repository access", select "Only select repositories"
# 6. Choose this repository (megalinter-custom-flavor-npm-groovy-lint)
# 7. Under "Permissions" > "Repository permissions":
# - Contents: Read and write
# - Actions: Read and write
# 8. Click "Generate token" and copy the token
# 9. In your repository, go to Settings > Secrets and variables > Actions
# 10. Click "New repository secret"
# 11. Name: PAT_TOKEN, Value: paste your token
# =============================================================
name: Check for New MegaLinter Version
on:
schedule:
# Run daily at 00:00 UTC
- cron: "0 0 * * *"
workflow_dispatch:
permissions:
contents: write
jobs:
check-new-version:
name: Check for New MegaLinter Version
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v6
with:
fetch-depth: 0
persist-credentials: false
- name: Fetch MegaLinter Repository Tags
id: fetch-megalinter-tags
run: |
echo "Fetching tags from oxsecurity/megalinter..."
# Fetch all tags from MegaLinter repository (filtering for version tags only)
MEGALINTER_TAGS=$(git ls-remote --tags --refs https://github.com/oxsecurity/megalinter.git | \
grep -E 'refs/tags/v[0-9]+\.[0-9]+\.[0-9]+$' | \
sed 's/.*refs\/tags\///' | \
sort -V | \
tail -n 20)
echo "Latest MegaLinter tags:"
echo "$MEGALINTER_TAGS"
# Get the latest tag
LATEST_MEGALINTER_TAG=$(echo "$MEGALINTER_TAGS" | tail -n 1)
echo "latest_tag=$LATEST_MEGALINTER_TAG" >> $GITHUB_OUTPUT
# Save all tags to a file
echo "$MEGALINTER_TAGS" > megalinter_tags.txt
- name: Fetch Current Repository Tags
id: fetch-repo-tags
run: |
echo "Fetching tags from current repository..."
# Fetch all version tags from current repository
REPO_TAGS=$(git tag -l 'v*' | sort -V)
echo "Current repository tags:"
echo "$REPO_TAGS"
# Get the latest tag from current repository
if [ -z "$REPO_TAGS" ]; then
LATEST_REPO_TAG=""
echo "No existing tags in repository"
else
LATEST_REPO_TAG=$(echo "$REPO_TAGS" | tail -n 1)
echo "Latest repository tag: $LATEST_REPO_TAG"
fi
echo "latest_repo_tag=$LATEST_REPO_TAG" >> $GITHUB_OUTPUT
- name: Find New Version
id: find-new-version
env:
LATEST_MEGALINTER_TAG: ${{ steps.fetch-megalinter-tags.outputs.latest_tag }}
LATEST_REPO_TAG: ${{ steps.fetch-repo-tags.outputs.latest_repo_tag }}
run: |
echo "Comparing versions..."
echo "Latest MegaLinter tag: $LATEST_MEGALINTER_TAG"
echo "Latest repository tag: $LATEST_REPO_TAG"
# Function to compare semantic versions
version_greater_than() {
# Remove 'v' prefix for comparison
ver1="${1#v}"
ver2="${2#v}"
# Use sort -V to compare versions
if [ "$(printf '%s\n' "$ver1" "$ver2" | sort -V | tail -n1)" = "$ver1" ] && [ "$ver1" != "$ver2" ]; then
return 0 # ver1 > ver2
else
return 1 # ver1 <= ver2
fi
}
# Check if we should create a new release
if [ -z "$LATEST_REPO_TAG" ]; then
echo "No existing tags in repository. Will create release for $LATEST_MEGALINTER_TAG"
echo "new_version_found=true" >> $GITHUB_OUTPUT
echo "new_version=$LATEST_MEGALINTER_TAG" >> $GITHUB_OUTPUT
elif version_greater_than "$LATEST_MEGALINTER_TAG" "$LATEST_REPO_TAG"; then
echo "✅ New version found! $LATEST_MEGALINTER_TAG > $LATEST_REPO_TAG"
echo "new_version_found=true" >> $GITHUB_OUTPUT
echo "new_version=$LATEST_MEGALINTER_TAG" >> $GITHUB_OUTPUT
else
echo "ℹ️ No new version. Repository is up to date."
echo "new_version_found=false" >> $GITHUB_OUTPUT
fi
- name: Create Release for New Version
if: steps.find-new-version.outputs.new_version_found == 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NEW_VERSION: ${{ steps.find-new-version.outputs.new_version }}
run: |
echo "Creating release for version $NEW_VERSION..."
# Create a release using GitHub CLI (will also create the tag)
gh release create "$NEW_VERSION" \
--title "MegaLinter Custom Flavor $NEW_VERSION" \
--notes "Automated release to sync with MegaLinter version $NEW_VERSION.
This release was automatically created to build a custom MegaLinter flavor based on the upstream MegaLinter release $NEW_VERSION.
For more information about changes in this version, see the [MegaLinter changelog](https://github.com/oxsecurity/megalinter/releases/tag/$NEW_VERSION)." \
--latest
- name: Trigger Custom Flavor Builder Workflow
if: steps.find-new-version.outputs.new_version_found == 'true'
env:
# Use PAT_TOKEN if available, otherwise fall back to GITHUB_TOKEN
# Note: GITHUB_TOKEN doesn't have permission to trigger workflows
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN || secrets.GITHUB_TOKEN }}
NEW_VERSION: ${{ steps.find-new-version.outputs.new_version }}
run: |
echo "Triggering megalinter-custom-flavor-builder workflow..."
# Trigger the workflow using GitHub CLI and capture output
set +e # Don't exit immediately on error
gh workflow run megalinter-custom-flavor-builder.yml \
--ref main \
--field megalinter-version="$NEW_VERSION" \
--field is-latest="true" \
2>&1 | tee workflow_trigger.log
EXIT_CODE=$?
set -e # Re-enable exit on error
# Check for errors in the output
if grep -q "could not create workflow dispatch event" workflow_trigger.log || \
grep -q "Resource not accessible by integration" workflow_trigger.log || \
grep -q "HTTP 403" workflow_trigger.log || \
[ $EXIT_CODE -ne 0 ]; then
echo "::error::❌ Failed to trigger workflow!"
echo ""
cat workflow_trigger.log
echo ""
if grep -q "Resource not accessible by integration" workflow_trigger.log || grep -q "HTTP 403" workflow_trigger.log; then
echo "::error::The workflow could not be triggered due to insufficient token permissions."
echo "::error::"
echo "::error::Deleting the release so it can be recreated once PAT_TOKEN is configured..."
# Delete the release and tag that was just created
gh release delete "$NEW_VERSION" --yes --cleanup-tag 2>&1 || echo "::warning::Could not delete release (it may not exist or already be deleted)"
echo "::error::"
echo "::error::⚠️ PAT_TOKEN is REQUIRED to create releases and trigger the builder workflow."
echo "::error::"
echo "::error::To fix this, create a Fine-grained Personal Access Token (recommended - more secure):"
echo "::error::1. Go to: https://github.com/settings/personal-access-tokens/new"
echo "::error::2. Token name: 'MegaLinter Auto-Release'"
echo "::error::3. Expiration: Choose 90 days or 1 year"
echo "::error::4. Repository access: Select 'Only select repositories'"
echo "::error::5. Choose repository: ${GITHUB_REPOSITORY}"
echo "::error::6. Repository permissions:"
echo "::error:: - Contents: Read and write"
echo "::error:: - Actions: Read and write"
echo "::error::7. Click 'Generate token' and copy it"
echo "::error::8. Go to: https://github.com/${GITHUB_REPOSITORY}/settings/secrets/actions"
echo "::error::9. Click 'New repository secret'"
echo "::error::10. Name: 'PAT_TOKEN', Value: paste your token"
echo "::error::"
echo "::error::Once configured, run this workflow again (manually or wait for the next scheduled run)."
fi
exit 1
fi
echo "✅ Builder workflow triggered successfully with version: $NEW_VERSION"
- name: Summary
if: always()
env:
LATEST_MEGALINTER_TAG: ${{ steps.fetch-megalinter-tags.outputs.latest_tag }}
LATEST_REPO_TAG: ${{ steps.fetch-repo-tags.outputs.latest_repo_tag }}
NEW_VERSION_FOUND: ${{ steps.find-new-version.outputs.new_version_found }}
NEW_VERSION: ${{ steps.find-new-version.outputs.new_version }}
GH_REPO: ${GITHUB_REPOSITORY}
run: |
echo "## Check for New MegaLinter Version Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [ "${NEW_VERSION_FOUND}" == "true" ]; then
echo "New version found: **${NEW_VERSION}**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "A new release has been created, which will trigger the custom flavor builder workflow." >> $GITHUB_STEP_SUMMARY
else
echo "No new versions found. Repository is up to date with MegaLinter." >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Version Comparison:**" >> $GITHUB_STEP_SUMMARY
echo "- Latest MegaLinter version: **$LATEST_MEGALINTER_TAG**" >> $GITHUB_STEP_SUMMARY
if [ -n "$LATEST_REPO_TAG" ]; then
echo "- Latest repository version: **$LATEST_REPO_TAG**" >> $GITHUB_STEP_SUMMARY
else
echo "- Latest repository version: **No tags found**" >> $GITHUB_STEP_SUMMARY
fi