Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 96 additions & 45 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,49 @@ name: 🚀 MerphDev — Pipeline CI/CD
on:
push:
branches: [main]

pull_request:
branches: [main]

schedule:
- cron: '0 0 * * 1' # Every Monday at midnight — weekly check
- cron: '0 0 * * 1'

jobs:
# ─── JOB 1: STRUCTURE VALIDATION ───

# ─── JOB 1 ───
validate:

name: ✅ Validate project structure
runs-on: ubuntu-latest

steps:

- name: Checkout code
uses: actions/checkout@v4

- name: Check required files exist
run: |

echo "Checking project structure..."

required_files=(
"README.md"

"learning-paths/cybersecurity.md"
"learning-paths/ai-ml.md"
"learning-paths/devops-cloud.md"
"learning-paths/web-fullstack.md"
"learning-paths/git-github.md"

"certifications/README.md"
"notes/README.md"
"notebooks/README.md"
"models/README.md"

"docs/ROADMAP.md"
)

all_ok=true

for file in "${required_files[@]}"; do
if [ ! -f "$file" ]; then
echo "❌ MISSING: $file"
Expand All @@ -41,94 +54,132 @@ jobs:
echo "✅ OK: $file"
fi
done

if [ "$all_ok" = false ]; then
echo "❌ Validation failed — missing files"
echo "❌ Validation failed"
exit 1
fi
echo "✅ All structure is valid"

echo "✅ Structure OK"

- name: Validate Markdown syntax
uses: DavidAnson/markdownlint-cli2-action@v16
with:
args: --config .markdownlint.json .
continue-on-error: true

# ─── JOB 2: LINK CHECKING ───

# ─── JOB 2 ───
check-links:

name: 🔗 Check external links
runs-on: ubuntu-latest
needs: validate

steps:

- name: Checkout code
uses: actions/checkout@v4

- name: Install link checking tool
- name: Install tool
run: npm install -g markdown-link-check

- name: Check links in all Markdown files
- name: Check links
run: |
echo "Checking external links..."
find . -name "*.md" -not -path "./node_modules/*" | while read file; do
echo "─── Checking: $file ───"
markdown-link-check "$file" --config .linkcheck.json || true
done

# ─── JOB 3: REPORT GENERATION ───
echo "Checking links..."

find . -name "*.md" \
-not -path "./node_modules/*" \
| while read file; do

echo "Checking: $file"

markdown-link-check "$file" \
--config .linkcheck.json \
|| true

done


# ─── JOB 3 ───
report:

name: 📊 Generate progress report
runs-on: ubuntu-latest
needs: validate

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v5
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Generate report
run: |

python3 << 'EOF'
import os, json
from datetime import datetime
report = {
"generated_at": datetime.now().isoformat(),
"project": "MerphDev Learning and Certifications",
"statistics": {}
}
# Count Markdown files per directory
dirs_to_scan = ["learning-paths", "certifications", "notes", "models", "docs"]
for d in dirs_to_scan:
if os.path.exists(d):
md_files = [f for f in os.listdir(d) if f.endswith('.md')]
report["statistics"][d] = len(md_files)
with open("docs/latest-report.json", "w") as f:
json.dump(report, f, indent=2)
print("✅ Report generated:", json.dumps(report, indent=2))
EOF

- name: Upload report as artifact
uses: actions/upload-artifact@v4

import os, json
Comment thread
FullStackFlow-dev marked this conversation as resolved.
from datetime import datetime

report = {
"generated_at": datetime.now().isoformat(),
"project": "MerphDev",
"statistics": {}
}

dirs = [
"learning-paths",
"certifications",
"notebooks",
"models",
"docs"
]

for d in dirs:
if os.path.exists(d):
md_files = [
f for f in os.listdir(d)
if f.endswith('.md')
]
report["statistics"][d] = len(md_files)

os.makedirs("docs", exist_ok=True)

with open("docs/latest-report.json","w") as f:
json.dump(report,f,indent=2)

print("Report generated")

EOF
Comment thread
coderabbitai[bot] marked this conversation as resolved.

- uses: actions/upload-artifact@v4
with:
name: progress-report
path: docs/latest-report.json
Comment on lines +159 to 162
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

wc -l .github/workflows/ci-cd.yml

Repository: FullStackFlow-dev/Merph-dev-Portfolio

Length of output: 112


🏁 Script executed:

cat -n .github/workflows/ci-cd.yml | sed -n '150,200p'

Repository: FullStackFlow-dev/Merph-dev-Portfolio

Length of output: 1036


Download the generated report artifact before publishing to GitHub Pages.

Lines 159-162 upload docs/latest-report.json as an artifact in the report job, but the deploy job (lines 179-185) never downloads it. Each GitHub Actions job runs in its own workspace. The fresh checkout in the deploy job at line 179 will publish the stale ./docs from the repository, not the newly generated report.

📦 Proposed fix
       - uses: actions/checkout@v4
+
+      - uses: actions/download-artifact@v4
+        with:
+          name: progress-report
+          path: .
 
       - uses: peaceiris/actions-gh-pages@v4
         with:
           github_token: ${{ secrets.GITHUB_TOKEN }}
           publish_dir: ./docs
           publish_branch: gh-pages
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/ci-cd.yml around lines 159 - 162, The deploy job is
publishing a stale ./docs because the report job uploads docs/latest-report.json
as an artifact (actions/upload-artifact@v4) but deploy never downloads it; add
an actions/download-artifact@v4 step in the deploy job (using name:
progress-report) before the GitHub Pages publish step so the generated
docs/latest-report.json is restored into the workspace (or into ./docs) and then
published; update the download step to place the artifact at the expected path
so the existing publish step can pick up the new report.

✅ Confirmed as addressed by @FullStackFlow-dev

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

   - uses: actions/checkout@v4
  •  - uses: actions/download-artifact@v4
    
  •    with:
    
  •      name: progress-report
    
  •      path: .
    
     - uses: peaceiris/actions-gh-pages@v4
       with:
         github_token: ${{ secrets.GITHUB_TOKEN }}
         publish_dir: ./docs
         publish_branch: gh-pages
    

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@FullStackFlow-dev, great — that's exactly the fix needed! With actions/download-artifact@v4 added before the GitHub Pages publish step, the freshly generated docs/latest-report.json will be restored into the workspace and correctly deployed instead of the stale version from the repository checkout. ✅

(_(
(-.-)
o_(")(")


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!


# ─── JOB 4: DEPLOYMENT ───

# ─── JOB 4 ───
deploy:

name: 🚀 Deploy to GitHub Pages
runs-on: ubuntu-latest
needs: [validate, report]

if: github.ref == 'refs/heads/main'

permissions:
contents: write

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
- uses: actions/checkout@v4

- uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs
publish_branch: gh-pages
commit_message: "docs: deploy latest documentation [CI/CD]"
publish_branch: gh-pages