Skip to content

Commit e4fe720

Browse files
dev: install custom flavor of megalinter for zensical projects
Used Megalinter runner tool to create the custom image, passing the specific tools to include (avoiding the need to select them individually). ```shell npx mega-linter-runner --custom-flavor-setup --custom-flavor-linters MARKDOWN_MARKDOWN_TABLE_FORMATTER,MARKDOWN_RUMDL,REPOSITORY_BETTERLEAKS,SPELL_LYCHEE,YAML_V8R ```
1 parent a92cd50 commit e4fe720

5 files changed

Lines changed: 507 additions & 2 deletions

File tree

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
---
2+
# =============================================================
3+
# Check for New MegaLinter Version Workflow
4+
#
5+
# This workflow checks daily for new versions of the MegaLinter
6+
# custom-builder action and creates a release if a new version is found.
7+
#
8+
# Usage:
9+
# - Runs daily at 00:00 UTC via schedule
10+
# - Can be manually triggered via workflow_dispatch
11+
# - Compares MegaLinter tags with current repository tags
12+
# - Creates a new release if a new MegaLinter version is detected
13+
#
14+
# The workflow will:
15+
# 1. Fetch all tags from oxsecurity/megalinter repository
16+
# 2. Fetch all tags from the current repository
17+
# 3. Find new tags that exist in MegaLinter but not in current repo
18+
# 4. Create a release with the new version tag
19+
# 5. The release will trigger megalinter-custom-flavor-builder.yml
20+
#
21+
# Required permissions:
22+
# - contents: write (to create releases and tags)
23+
#
24+
# Required repository secrets:
25+
# - PAT_TOKEN: Personal Access Token with 'contents' and 'actions' permissions
26+
# This is required to trigger the builder workflow. Without it, the workflow
27+
# will fail and the release will be deleted (to be recreated once the token is set).
28+
#
29+
# SECURITY WARNING: Using a PAT comes with risk. Open-source projects have been
30+
# heavily targeted by supply-chain attacks in recent months, and a leaked or
31+
# compromised PAT can give attackers broad write access to your repository —
32+
# better safe than sorry! If you do not need fully automatic daily version
33+
# sync, you can skip the PAT entirely and trigger this workflow manually
34+
# (Actions tab → "Check for New MegaLinter Version" → "Run workflow") whenever
35+
# you want to bump to a new MegaLinter release. Only configure PAT_TOKEN if
36+
# the daily automation is worth the trade-off, and always scope it to this
37+
# single repository with the minimum required permissions.
38+
#
39+
# To create a Fine-grained PAT (still discouraged unless you need automation):
40+
# 1. Go to GitHub Settings > Developer settings > Personal access tokens > Fine-grained tokens
41+
# 2. Click "Generate new token"
42+
# 3. Give it a descriptive name (e.g., "MegaLinter Auto-Release")
43+
# 4. Set expiration (e.g., 90 days or 1 year)
44+
# 5. Under "Repository access", select "Only select repositories"
45+
# 6. Choose this repository (megalinter-custom-flavor-npm-groovy-lint)
46+
# 7. Under "Permissions" > "Repository permissions":
47+
# - Contents: Read and write
48+
# - Actions: Read and write
49+
# 8. Click "Generate token" and copy the token
50+
# 9. In your repository, go to Settings > Secrets and variables > Actions
51+
# 10. Click "New repository secret"
52+
# 11. Name: PAT_TOKEN, Value: paste your token
53+
# =============================================================
54+
name: Check for New MegaLinter Version
55+
56+
on:
57+
schedule:
58+
# Run daily at 00:00 UTC
59+
- cron: "0 0 * * *"
60+
workflow_dispatch:
61+
62+
permissions:
63+
contents: write
64+
65+
jobs:
66+
check-new-version:
67+
name: Check for New MegaLinter Version
68+
runs-on: ubuntu-latest
69+
70+
steps:
71+
- name: Checkout Code
72+
uses: actions/checkout@v6
73+
with:
74+
fetch-depth: 0
75+
persist-credentials: false
76+
77+
- name: Fetch MegaLinter Repository Tags
78+
id: fetch-megalinter-tags
79+
run: |
80+
echo "Fetching tags from oxsecurity/megalinter..."
81+
82+
# Fetch all tags from MegaLinter repository (filtering for version tags only)
83+
MEGALINTER_TAGS=$(git ls-remote --tags --refs https://github.com/oxsecurity/megalinter.git | \
84+
grep -E 'refs/tags/v[0-9]+\.[0-9]+\.[0-9]+$' | \
85+
sed 's/.*refs\/tags\///' | \
86+
sort -V | \
87+
tail -n 20)
88+
89+
echo "Latest MegaLinter tags:"
90+
echo "$MEGALINTER_TAGS"
91+
92+
# Get the latest tag
93+
LATEST_MEGALINTER_TAG=$(echo "$MEGALINTER_TAGS" | tail -n 1)
94+
echo "latest_tag=$LATEST_MEGALINTER_TAG" >> $GITHUB_OUTPUT
95+
96+
# Save all tags to a file
97+
echo "$MEGALINTER_TAGS" > megalinter_tags.txt
98+
99+
- name: Fetch Current Repository Tags
100+
id: fetch-repo-tags
101+
run: |
102+
echo "Fetching tags from current repository..."
103+
104+
# Fetch all version tags from current repository
105+
REPO_TAGS=$(git tag -l 'v*' | sort -V)
106+
107+
echo "Current repository tags:"
108+
echo "$REPO_TAGS"
109+
110+
# Get the latest tag from current repository
111+
if [ -z "$REPO_TAGS" ]; then
112+
LATEST_REPO_TAG=""
113+
echo "No existing tags in repository"
114+
else
115+
LATEST_REPO_TAG=$(echo "$REPO_TAGS" | tail -n 1)
116+
echo "Latest repository tag: $LATEST_REPO_TAG"
117+
fi
118+
119+
echo "latest_repo_tag=$LATEST_REPO_TAG" >> $GITHUB_OUTPUT
120+
121+
- name: Find New Version
122+
id: find-new-version
123+
env:
124+
LATEST_MEGALINTER_TAG: ${{ steps.fetch-megalinter-tags.outputs.latest_tag }}
125+
LATEST_REPO_TAG: ${{ steps.fetch-repo-tags.outputs.latest_repo_tag }}
126+
run: |
127+
echo "Comparing versions..."
128+
129+
echo "Latest MegaLinter tag: $LATEST_MEGALINTER_TAG"
130+
echo "Latest repository tag: $LATEST_REPO_TAG"
131+
132+
# Function to compare semantic versions
133+
version_greater_than() {
134+
# Remove 'v' prefix for comparison
135+
ver1="${1#v}"
136+
ver2="${2#v}"
137+
138+
# Use sort -V to compare versions
139+
if [ "$(printf '%s\n' "$ver1" "$ver2" | sort -V | tail -n1)" = "$ver1" ] && [ "$ver1" != "$ver2" ]; then
140+
return 0 # ver1 > ver2
141+
else
142+
return 1 # ver1 <= ver2
143+
fi
144+
}
145+
146+
# Check if we should create a new release
147+
if [ -z "$LATEST_REPO_TAG" ]; then
148+
echo "No existing tags in repository. Will create release for $LATEST_MEGALINTER_TAG"
149+
echo "new_version_found=true" >> $GITHUB_OUTPUT
150+
echo "new_version=$LATEST_MEGALINTER_TAG" >> $GITHUB_OUTPUT
151+
elif version_greater_than "$LATEST_MEGALINTER_TAG" "$LATEST_REPO_TAG"; then
152+
echo "✅ New version found! $LATEST_MEGALINTER_TAG > $LATEST_REPO_TAG"
153+
echo "new_version_found=true" >> $GITHUB_OUTPUT
154+
echo "new_version=$LATEST_MEGALINTER_TAG" >> $GITHUB_OUTPUT
155+
else
156+
echo "ℹ️ No new version. Repository is up to date."
157+
echo "new_version_found=false" >> $GITHUB_OUTPUT
158+
fi
159+
160+
- name: Create Release for New Version
161+
if: steps.find-new-version.outputs.new_version_found == 'true'
162+
env:
163+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
164+
NEW_VERSION: ${{ steps.find-new-version.outputs.new_version }}
165+
run: |
166+
echo "Creating release for version $NEW_VERSION..."
167+
168+
# Create a release using GitHub CLI (will also create the tag)
169+
gh release create "$NEW_VERSION" \
170+
--title "MegaLinter Custom Flavor $NEW_VERSION" \
171+
--notes "Automated release to sync with MegaLinter version $NEW_VERSION.
172+
173+
This release was automatically created to build a custom MegaLinter flavor based on the upstream MegaLinter release $NEW_VERSION.
174+
175+
For more information about changes in this version, see the [MegaLinter changelog](https://github.com/oxsecurity/megalinter/releases/tag/$NEW_VERSION)." \
176+
--latest
177+
178+
- name: Trigger Custom Flavor Builder Workflow
179+
if: steps.find-new-version.outputs.new_version_found == 'true'
180+
env:
181+
# Use PAT_TOKEN if available, otherwise fall back to GITHUB_TOKEN
182+
# Note: GITHUB_TOKEN doesn't have permission to trigger workflows
183+
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN || secrets.GITHUB_TOKEN }}
184+
NEW_VERSION: ${{ steps.find-new-version.outputs.new_version }}
185+
run: |
186+
echo "Triggering megalinter-custom-flavor-builder workflow..."
187+
188+
# Trigger the workflow using GitHub CLI and capture output
189+
set +e # Don't exit immediately on error
190+
gh workflow run megalinter-custom-flavor-builder.yml \
191+
--ref main \
192+
--field megalinter-version="$NEW_VERSION" \
193+
--field is-latest="true" \
194+
2>&1 | tee workflow_trigger.log
195+
EXIT_CODE=$?
196+
set -e # Re-enable exit on error
197+
198+
# Check for errors in the output
199+
if grep -q "could not create workflow dispatch event" workflow_trigger.log || \
200+
grep -q "Resource not accessible by integration" workflow_trigger.log || \
201+
grep -q "HTTP 403" workflow_trigger.log || \
202+
[ $EXIT_CODE -ne 0 ]; then
203+
204+
echo "::error::❌ Failed to trigger workflow!"
205+
echo ""
206+
cat workflow_trigger.log
207+
echo ""
208+
209+
if grep -q "Resource not accessible by integration" workflow_trigger.log || grep -q "HTTP 403" workflow_trigger.log; then
210+
echo "::error::The workflow could not be triggered due to insufficient token permissions."
211+
echo "::error::"
212+
echo "::error::Deleting the release so it can be recreated once PAT_TOKEN is configured..."
213+
214+
# Delete the release and tag that was just created
215+
gh release delete "$NEW_VERSION" --yes --cleanup-tag 2>&1 || echo "::warning::Could not delete release (it may not exist or already be deleted)"
216+
217+
echo "::error::"
218+
echo "::error::⚠️ PAT_TOKEN is REQUIRED to create releases and trigger the builder workflow."
219+
echo "::error::"
220+
echo "::error::To fix this, create a Fine-grained Personal Access Token (recommended - more secure):"
221+
echo "::error::1. Go to: https://github.com/settings/personal-access-tokens/new"
222+
echo "::error::2. Token name: 'MegaLinter Auto-Release'"
223+
echo "::error::3. Expiration: Choose 90 days or 1 year"
224+
echo "::error::4. Repository access: Select 'Only select repositories'"
225+
echo "::error::5. Choose repository: ${GITHUB_REPOSITORY}"
226+
echo "::error::6. Repository permissions:"
227+
echo "::error:: - Contents: Read and write"
228+
echo "::error:: - Actions: Read and write"
229+
echo "::error::7. Click 'Generate token' and copy it"
230+
echo "::error::8. Go to: https://github.com/${GITHUB_REPOSITORY}/settings/secrets/actions"
231+
echo "::error::9. Click 'New repository secret'"
232+
echo "::error::10. Name: 'PAT_TOKEN', Value: paste your token"
233+
echo "::error::"
234+
echo "::error::Once configured, run this workflow again (manually or wait for the next scheduled run)."
235+
fi
236+
237+
exit 1
238+
fi
239+
240+
echo "✅ Builder workflow triggered successfully with version: $NEW_VERSION"
241+
242+
- name: Summary
243+
if: always()
244+
env:
245+
LATEST_MEGALINTER_TAG: ${{ steps.fetch-megalinter-tags.outputs.latest_tag }}
246+
LATEST_REPO_TAG: ${{ steps.fetch-repo-tags.outputs.latest_repo_tag }}
247+
NEW_VERSION_FOUND: ${{ steps.find-new-version.outputs.new_version_found }}
248+
NEW_VERSION: ${{ steps.find-new-version.outputs.new_version }}
249+
GH_REPO: ${GITHUB_REPOSITORY}
250+
run: |
251+
echo "## Check for New MegaLinter Version Summary" >> $GITHUB_STEP_SUMMARY
252+
echo "" >> $GITHUB_STEP_SUMMARY
253+
254+
if [ "${NEW_VERSION_FOUND}" == "true" ]; then
255+
echo "New version found: **${NEW_VERSION}**" >> $GITHUB_STEP_SUMMARY
256+
echo "" >> $GITHUB_STEP_SUMMARY
257+
echo "A new release has been created, which will trigger the custom flavor builder workflow." >> $GITHUB_STEP_SUMMARY
258+
else
259+
echo "No new versions found. Repository is up to date with MegaLinter." >> $GITHUB_STEP_SUMMARY
260+
fi
261+
262+
echo "" >> $GITHUB_STEP_SUMMARY
263+
echo "**Version Comparison:**" >> $GITHUB_STEP_SUMMARY
264+
echo "- Latest MegaLinter version: **$LATEST_MEGALINTER_TAG**" >> $GITHUB_STEP_SUMMARY
265+
266+
if [ -n "$LATEST_REPO_TAG" ]; then
267+
echo "- Latest repository version: **$LATEST_REPO_TAG**" >> $GITHUB_STEP_SUMMARY
268+
else
269+
echo "- Latest repository version: **No tags found**" >> $GITHUB_STEP_SUMMARY
270+
fi

0 commit comments

Comments
 (0)