[{"data":1,"prerenderedAt":75},["Reactive",2],{"blog-post-markdown-automation-workflows-complete-guide":3},{"slug":4,"title":5,"description":6,"excerpt":7,"date":8,"category":9,"author":10,"keywords":11,"readingMinutes":12,"html":13,"headings":14,"tools":49,"related":50},"markdown-automation-workflows-complete-guide","Markdown Automation Workflows: Complete Guide for CI/CD, Publishing, and Documentation Generation","Master automated Markdown workflows for continuous documentation, publishing pipelines, and content generation. Learn GitHub Actions, automated testing, deployment strategies, and integration with modern development tools.","Automated Markdown workflows enable seamless integration of documentation and content creation into modern development processes, providing continuous integration capabilities for technical…","2025-09-25","Tutorial","Matthew Rathbone","markdown automation, markdown ci cd, automated documentation, markdown workflows, markdown publishing automation, documentation generation, markdown testing, automated content publishing",29,"\u003Cp>Automated Markdown workflows enable seamless integration of documentation and content creation into modern development processes, providing continuous integration capabilities for technical writing, automated publishing pipelines, and sophisticated content generation systems. By implementing automated testing, validation, and deployment strategies for Markdown content, teams can maintain high-quality documentation standards while reducing manual overhead and ensuring consistency across large-scale content repositories.\u003C/p>\n\u003Ch2 id=\"why-master-markdown-automation-workflows\">Why Master Markdown Automation Workflows?\u003C/h2>\n\u003Cp>Professional Markdown automation provides essential benefits for modern development teams:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Continuous Documentation\u003C/strong>: Automatically generate and update documentation from code changes\u003C/li>\n\u003Cli>\u003Cstrong>Quality Assurance\u003C/strong>: Validate links, spelling, formatting, and content structure automatically  \u003C/li>\n\u003Cli>\u003Cstrong>Publishing Automation\u003C/strong>: Deploy documentation and content updates without manual intervention\u003C/li>\n\u003Cli>\u003Cstrong>Version Control Integration\u003C/strong>: Seamlessly integrate content workflows with Git-based development processes\u003C/li>\n\u003Cli>\u003Cstrong>Scalable Content Management\u003C/strong>: Handle large documentation repositories with automated maintenance and updates\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"foundation-automation-architecture\">Foundation Automation Architecture\u003C/h2>\n\u003Ch3 id=\"github-actions-for-markdown-workflows\">GitHub Actions for Markdown Workflows\u003C/h3>\n\u003Cp>Setting up comprehensive automation using GitHub Actions for Markdown content management:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-yaml\">\u003Cspan class=\"hljs-comment\"># .github/workflows/markdown-automation.yml - Complete automation pipeline\u003C/span>\n\u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Markdown\u003C/span> \u003Cspan class=\"hljs-string\">Content\u003C/span> \u003Cspan class=\"hljs-string\">Automation\u003C/span>\n\n\u003Cspan class=\"hljs-attr\">on:\u003C/span>\n  \u003Cspan class=\"hljs-attr\">push:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">branches:\u003C/span> [\u003Cspan class=\"hljs-string\">main\u003C/span>, \u003Cspan class=\"hljs-string\">develop\u003C/span>]\n    \u003Cspan class=\"hljs-attr\">paths:\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;**/*.md&#x27;\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;_posts/**/*&#x27;\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;docs/**/*&#x27;\u003C/span>\n  \u003Cspan class=\"hljs-attr\">pull_request:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">branches:\u003C/span> [\u003Cspan class=\"hljs-string\">main\u003C/span>]\n    \u003Cspan class=\"hljs-attr\">paths:\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;**/*.md&#x27;\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;_posts/**/*&#x27;\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;docs/**/*&#x27;\u003C/span>\n  \u003Cspan class=\"hljs-attr\">schedule:\u003C/span>\n    \u003Cspan class=\"hljs-comment\"># Run daily at 2 AM UTC for maintenance tasks\u003C/span>\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">cron:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;0 2 * * *&#x27;\u003C/span>\n  \u003Cspan class=\"hljs-attr\">workflow_dispatch:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">inputs:\u003C/span>\n      \u003Cspan class=\"hljs-attr\">deploy_environment:\u003C/span>\n        \u003Cspan class=\"hljs-attr\">description:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;Deployment environment&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-attr\">required:\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>\n        \u003Cspan class=\"hljs-attr\">default:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;staging&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-attr\">type:\u003C/span> \u003Cspan class=\"hljs-string\">choice\u003C/span>\n        \u003Cspan class=\"hljs-attr\">options:\u003C/span>\n          \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">staging\u003C/span>\n          \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">production\u003C/span>\n\n\u003Cspan class=\"hljs-attr\">env:\u003C/span>\n  \u003Cspan class=\"hljs-attr\">NODE_VERSION:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;18&#x27;\u003C/span>\n  \u003Cspan class=\"hljs-attr\">RUBY_VERSION:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;3.0&#x27;\u003C/span>\n  \u003Cspan class=\"hljs-attr\">PYTHON_VERSION:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;3.9&#x27;\u003C/span>\n\n\u003Cspan class=\"hljs-attr\">jobs:\u003C/span>\n  \u003Cspan class=\"hljs-comment\"># Content validation and quality checks\u003C/span>\n  \u003Cspan class=\"hljs-attr\">content-validation:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;Content Validation &amp; Quality Checks&#x27;\u003C/span>\n    \u003Cspan class=\"hljs-attr\">runs-on:\u003C/span> \u003Cspan class=\"hljs-string\">ubuntu-latest\u003C/span>\n    \u003Cspan class=\"hljs-attr\">outputs:\u003C/span>\n      \u003Cspan class=\"hljs-attr\">validation-status:\u003C/span> \u003Cspan class=\"hljs-string\">${{\u003C/span> \u003Cspan class=\"hljs-string\">steps.validation.outputs.status\u003C/span> \u003Cspan class=\"hljs-string\">}}\u003C/span>\n      \u003Cspan class=\"hljs-attr\">changed-files:\u003C/span> \u003Cspan class=\"hljs-string\">${{\u003C/span> \u003Cspan class=\"hljs-string\">steps.changes.outputs.markdown\u003C/span> \u003Cspan class=\"hljs-string\">}}\u003C/span>\n    \n    \u003Cspan class=\"hljs-attr\">steps:\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Checkout\u003C/span> \u003Cspan class=\"hljs-string\">repository\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/checkout@v4\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">fetch-depth:\u003C/span> \u003Cspan class=\"hljs-number\">0\u003C/span>\n          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Setup\u003C/span> \u003Cspan class=\"hljs-string\">Node.js\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/setup-node@v3\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">node-version:\u003C/span> \u003Cspan class=\"hljs-string\">${{\u003C/span> \u003Cspan class=\"hljs-string\">env.NODE_VERSION\u003C/span> \u003Cspan class=\"hljs-string\">}}\u003C/span>\n          \u003Cspan class=\"hljs-attr\">cache:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;npm&#x27;\u003C/span>\n          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Install\u003C/span> \u003Cspan class=\"hljs-string\">dependencies\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          npm install -g markdownlint-cli\n          npm install -g markdown-link-check\n          npm install -g textlint\n          npm install -g alex\n          npm install -g remark-cli\n          npm install -g write-good\n\u003C/span>          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Detect\u003C/span> \u003Cspan class=\"hljs-string\">changed\u003C/span> \u003Cspan class=\"hljs-string\">files\u003C/span>\n        \u003Cspan class=\"hljs-attr\">id:\u003C/span> \u003Cspan class=\"hljs-string\">changes\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">dorny/paths-filter@v2\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">filters:\u003C/span> \u003Cspan class=\"hljs-string\">|\n            markdown:\n              - &#x27;**/*.md&#x27;\n              - &#x27;**/*.markdown&#x27;\n              \n\u003C/span>      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Lint\u003C/span> \u003Cspan class=\"hljs-string\">Markdown\u003C/span> \u003Cspan class=\"hljs-string\">files\u003C/span>\n        \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">steps.changes.outputs.markdown\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;true&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          echo &quot;Running markdown linting...&quot;\n          markdownlint **/*.md --config .markdownlint.json --output markdownlint-report.txt || true\n\u003C/span>          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Check\u003C/span> \u003Cspan class=\"hljs-string\">markdown\u003C/span> \u003Cspan class=\"hljs-string\">links\u003C/span>\n        \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">steps.changes.outputs.markdown\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;true&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          echo &quot;Checking markdown links...&quot;\n          find . -name &quot;*.md&quot; -not -path &quot;./node_modules/*&quot; -not -path &quot;./.git/*&quot; | \\\n          xargs markdown-link-check --config .markdown-link-check.json --progress || true\n\u003C/span>          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Text\u003C/span> \u003Cspan class=\"hljs-string\">quality\u003C/span> \u003Cspan class=\"hljs-string\">analysis\u003C/span>\n        \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">steps.changes.outputs.markdown\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;true&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          echo &quot;Running text quality analysis...&quot;\n          # Check for inclusive language\n          alex **/*.md --reporter json &gt; alex-report.json || true\n\u003C/span>          \n          \u003Cspan class=\"hljs-comment\"># Check writing quality\u003C/span>\n          \u003Cspan class=\"hljs-string\">write-good\u003C/span> \u003Cspan class=\"hljs-string\">**/*.md\u003C/span> \u003Cspan class=\"hljs-string\">--text\u003C/span> \u003Cspan class=\"hljs-string\">&gt;\u003C/span> \u003Cspan class=\"hljs-string\">write-good-report.txt\u003C/span> \u003Cspan class=\"hljs-string\">||\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>\n          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Spell\u003C/span> \u003Cspan class=\"hljs-string\">check\u003C/span>\n        \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">steps.changes.outputs.markdown\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;true&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          echo &quot;Running spell check...&quot;\n          # Install and run cspell\n          npm install -g cspell\n          cspell &quot;**/*.md&quot; --config .cspell.json --reporter @cspell/cspell-json-reporter &gt; cspell-report.json || true\n\u003C/span>          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Content\u003C/span> \u003Cspan class=\"hljs-string\">structure\u003C/span> \u003Cspan class=\"hljs-string\">validation\u003C/span>\n        \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">steps.changes.outputs.markdown\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;true&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          echo &quot;Validating content structure...&quot;\n          # Custom content validation script\n          python3 scripts/validate-content-structure.py\n\u003C/span>          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Generate\u003C/span> \u003Cspan class=\"hljs-string\">validation\u003C/span> \u003Cspan class=\"hljs-string\">report\u003C/span>\n        \u003Cspan class=\"hljs-attr\">id:\u003C/span> \u003Cspan class=\"hljs-string\">validation\u003C/span>\n        \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">steps.changes.outputs.markdown\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;true&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          echo &quot;Generating validation report...&quot;\n          python3 scripts/generate-validation-report.py\n          echo &quot;status=completed&quot; &gt;&gt; $GITHUB_OUTPUT\n\u003C/span>          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Upload\u003C/span> \u003Cspan class=\"hljs-string\">validation\u003C/span> \u003Cspan class=\"hljs-string\">artifacts\u003C/span>\n        \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">steps.changes.outputs.markdown\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;true&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/upload-artifact@v3\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">content-validation-reports\u003C/span>\n          \u003Cspan class=\"hljs-attr\">path:\u003C/span> \u003Cspan class=\"hljs-string\">|\n            markdownlint-report.txt\n            alex-report.json\n            write-good-report.txt\n            cspell-report.json\n            content-validation-report.html\n\u003C/span>          \u003Cspan class=\"hljs-attr\">retention-days:\u003C/span> \u003Cspan class=\"hljs-number\">30\u003C/span>\n          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Comment\u003C/span> \u003Cspan class=\"hljs-string\">PR\u003C/span> \u003Cspan class=\"hljs-string\">with\u003C/span> \u003Cspan class=\"hljs-string\">validation\u003C/span> \u003Cspan class=\"hljs-string\">results\u003C/span>\n        \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">github.event_name\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;pull_request&#x27;\u003C/span> \u003Cspan class=\"hljs-string\">&amp;&amp;\u003C/span> \u003Cspan class=\"hljs-string\">steps.changes.outputs.markdown\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;true&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/github-script@v6\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">script:\u003C/span> \u003Cspan class=\"hljs-string\">|\n            const fs = require(&#x27;fs&#x27;);\n            try {\n              const report = fs.readFileSync(&#x27;content-validation-summary.md&#x27;, &#x27;utf8&#x27;);\n              github.rest.issues.createComment({\n                issue_number: context.issue.number,\n                owner: context.repo.owner,\n                repo: context.repo.repo,\n                body: report\n              });\n            } catch (error) {\n              console.log(&#x27;No validation summary found or error creating comment&#x27;);\n            }\n\u003C/span>\n  \u003Cspan class=\"hljs-comment\"># Build and test documentation\u003C/span>\n  \u003Cspan class=\"hljs-attr\">build-documentation:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;Build &amp; Test Documentation&#x27;\u003C/span>\n    \u003Cspan class=\"hljs-attr\">runs-on:\u003C/span> \u003Cspan class=\"hljs-string\">ubuntu-latest\u003C/span>\n    \u003Cspan class=\"hljs-attr\">needs:\u003C/span> \u003Cspan class=\"hljs-string\">content-validation\u003C/span>\n    \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">needs.content-validation.outputs.changed-files\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;true&#x27;\u003C/span>\n    \n    \u003Cspan class=\"hljs-attr\">strategy:\u003C/span>\n      \u003Cspan class=\"hljs-attr\">matrix:\u003C/span>\n        \u003Cspan class=\"hljs-attr\">build-type:\u003C/span> [\u003Cspan class=\"hljs-string\">jekyll\u003C/span>, \u003Cspan class=\"hljs-string\">hugo\u003C/span>, \u003Cspan class=\"hljs-string\">mkdocs\u003C/span>]\n        \n    \u003Cspan class=\"hljs-attr\">steps:\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Checkout\u003C/span> \u003Cspan class=\"hljs-string\">repository\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/checkout@v4\u003C/span>\n        \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Setup\u003C/span> \u003Cspan class=\"hljs-string\">Ruby\u003C/span> \u003Cspan class=\"hljs-string\">(for\u003C/span> \u003Cspan class=\"hljs-string\">Jekyll)\u003C/span>\n        \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">matrix.build-type\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;jekyll&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">ruby/setup-ruby@v1\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">ruby-version:\u003C/span> \u003Cspan class=\"hljs-string\">${{\u003C/span> \u003Cspan class=\"hljs-string\">env.RUBY_VERSION\u003C/span> \u003Cspan class=\"hljs-string\">}}\u003C/span>\n          \u003Cspan class=\"hljs-attr\">bundler-cache:\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>\n          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Setup\u003C/span> \u003Cspan class=\"hljs-string\">Go\u003C/span> \u003Cspan class=\"hljs-string\">(for\u003C/span> \u003Cspan class=\"hljs-string\">Hugo)\u003C/span>\n        \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">matrix.build-type\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;hugo&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/setup-go@v4\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">go-version:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;1.19&#x27;\u003C/span>\n          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Setup\u003C/span> \u003Cspan class=\"hljs-string\">Python\u003C/span> \u003Cspan class=\"hljs-string\">(for\u003C/span> \u003Cspan class=\"hljs-string\">MkDocs)\u003C/span>\n        \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">matrix.build-type\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;mkdocs&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/setup-python@v4\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">python-version:\u003C/span> \u003Cspan class=\"hljs-string\">${{\u003C/span> \u003Cspan class=\"hljs-string\">env.PYTHON_VERSION\u003C/span> \u003Cspan class=\"hljs-string\">}}\u003C/span>\n          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Install\u003C/span> \u003Cspan class=\"hljs-string\">Jekyll\u003C/span> \u003Cspan class=\"hljs-string\">dependencies\u003C/span>\n        \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">matrix.build-type\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;jekyll&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          bundle install\n          bundle exec jekyll build --config _config.yml,_config_test.yml\n\u003C/span>          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Install\u003C/span> \u003Cspan class=\"hljs-string\">Hugo\u003C/span>\n        \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">matrix.build-type\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;hugo&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          wget https://github.com/gohugoio/hugo/releases/download/v0.111.3/hugo_extended_0.111.3_linux-amd64.tar.gz\n          tar -xzf hugo_extended_0.111.3_linux-amd64.tar.gz\n          sudo mv hugo /usr/local/bin/\n          hugo version\n          hugo --minify --destination public/\n\u003C/span>          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Install\u003C/span> \u003Cspan class=\"hljs-string\">MkDocs\u003C/span> \u003Cspan class=\"hljs-string\">dependencies\u003C/span>\n        \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">matrix.build-type\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;mkdocs&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          pip install -r requirements.txt\n          mkdocs build --strict --verbose\n\u003C/span>          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Test\u003C/span> \u003Cspan class=\"hljs-string\">generated\u003C/span> \u003Cspan class=\"hljs-string\">site\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          # Test HTML output\n          npm install -g htmlhint\n          find _site -name &quot;*.html&quot; | xargs htmlhint --config .htmlhintrc || true\n\u003C/span>          \n          \u003Cspan class=\"hljs-comment\"># Test accessibility\u003C/span>\n          \u003Cspan class=\"hljs-string\">npm\u003C/span> \u003Cspan class=\"hljs-string\">install\u003C/span> \u003Cspan class=\"hljs-string\">-g\u003C/span> \u003Cspan class=\"hljs-string\">pa11y-ci\u003C/span>\n          \u003Cspan class=\"hljs-string\">pa11y-ci\u003C/span> \u003Cspan class=\"hljs-string\">--sitemap\u003C/span> \u003Cspan class=\"hljs-string\">http://localhost:4000/sitemap.xml\u003C/span> \u003Cspan class=\"hljs-string\">--reporter\u003C/span> \u003Cspan class=\"hljs-string\">json\u003C/span> \u003Cspan class=\"hljs-string\">&gt;\u003C/span> \u003Cspan class=\"hljs-string\">pa11y-report.json\u003C/span> \u003Cspan class=\"hljs-string\">||\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>\n          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Upload\u003C/span> \u003Cspan class=\"hljs-string\">build\u003C/span> \u003Cspan class=\"hljs-string\">artifacts\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/upload-artifact@v3\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">built-site-${{\u003C/span> \u003Cspan class=\"hljs-string\">matrix.build-type\u003C/span> \u003Cspan class=\"hljs-string\">}}\u003C/span>\n          \u003Cspan class=\"hljs-attr\">path:\u003C/span> \u003Cspan class=\"hljs-string\">|\n            _site/\n            public/\n            site/\n\u003C/span>          \u003Cspan class=\"hljs-attr\">retention-days:\u003C/span> \u003Cspan class=\"hljs-number\">7\u003C/span>\n\n  \u003Cspan class=\"hljs-comment\"># Security and dependency scanning\u003C/span>\n  \u003Cspan class=\"hljs-attr\">security-scan:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;Security &amp; Dependency Scanning&#x27;\u003C/span>\n    \u003Cspan class=\"hljs-attr\">runs-on:\u003C/span> \u003Cspan class=\"hljs-string\">ubuntu-latest\u003C/span>\n    \n    \u003Cspan class=\"hljs-attr\">steps:\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Checkout\u003C/span> \u003Cspan class=\"hljs-string\">repository\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/checkout@v4\u003C/span>\n        \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Run\u003C/span> \u003Cspan class=\"hljs-string\">Trivy\u003C/span> \u003Cspan class=\"hljs-string\">vulnerability\u003C/span> \u003Cspan class=\"hljs-string\">scanner\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">aquasecurity/trivy-action@master\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">scan-type:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;fs&#x27;\u003C/span>\n          \u003Cspan class=\"hljs-attr\">scan-ref:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;.&#x27;\u003C/span>\n          \u003Cspan class=\"hljs-attr\">format:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;sarif&#x27;\u003C/span>\n          \u003Cspan class=\"hljs-attr\">output:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;trivy-results.sarif&#x27;\u003C/span>\n          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Upload\u003C/span> \u003Cspan class=\"hljs-string\">Trivy\u003C/span> \u003Cspan class=\"hljs-string\">scan\u003C/span> \u003Cspan class=\"hljs-string\">results\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">github/codeql-action/upload-sarif@v2\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">sarif_file:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;trivy-results.sarif&#x27;\u003C/span>\n          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Dependency\u003C/span> \u003Cspan class=\"hljs-string\">vulnerability\u003C/span> \u003Cspan class=\"hljs-string\">check\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          # Check npm dependencies\n          if [ -f package.json ]; then\n            npm audit --audit-level high --json &gt; npm-audit-report.json || true\n          fi\n\u003C/span>          \n          \u003Cspan class=\"hljs-comment\"># Check Ruby dependencies\u003C/span>\n          \u003Cspan class=\"hljs-string\">if\u003C/span> [ \u003Cspan class=\"hljs-string\">-f\u003C/span> \u003Cspan class=\"hljs-string\">Gemfile\u003C/span> ]\u003Cspan class=\"hljs-string\">;\u003C/span> \u003Cspan class=\"hljs-string\">then\u003C/span>\n            \u003Cspan class=\"hljs-string\">gem\u003C/span> \u003Cspan class=\"hljs-string\">install\u003C/span> \u003Cspan class=\"hljs-string\">bundler-audit\u003C/span>\n            \u003Cspan class=\"hljs-string\">bundle-audit\u003C/span> \u003Cspan class=\"hljs-string\">check\u003C/span> \u003Cspan class=\"hljs-string\">--update\u003C/span> \u003Cspan class=\"hljs-string\">--format\u003C/span> \u003Cspan class=\"hljs-string\">json\u003C/span> \u003Cspan class=\"hljs-string\">--output\u003C/span> \u003Cspan class=\"hljs-string\">bundler-audit-report.json\u003C/span> \u003Cspan class=\"hljs-string\">||\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>\n          \u003Cspan class=\"hljs-string\">fi\u003C/span>\n          \n          \u003Cspan class=\"hljs-comment\"># Check Python dependencies\u003C/span>\n          \u003Cspan class=\"hljs-string\">if\u003C/span> [ \u003Cspan class=\"hljs-string\">-f\u003C/span> \u003Cspan class=\"hljs-string\">requirements.txt\u003C/span> ]\u003Cspan class=\"hljs-string\">;\u003C/span> \u003Cspan class=\"hljs-string\">then\u003C/span>\n            \u003Cspan class=\"hljs-string\">pip\u003C/span> \u003Cspan class=\"hljs-string\">install\u003C/span> \u003Cspan class=\"hljs-string\">safety\u003C/span>\n            \u003Cspan class=\"hljs-string\">safety\u003C/span> \u003Cspan class=\"hljs-string\">check\u003C/span> \u003Cspan class=\"hljs-string\">--json\u003C/span> \u003Cspan class=\"hljs-string\">--output\u003C/span> \u003Cspan class=\"hljs-string\">safety-report.json\u003C/span> \u003Cspan class=\"hljs-string\">||\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>\n          \u003Cspan class=\"hljs-string\">fi\u003C/span>\n\n  \u003Cspan class=\"hljs-comment\"># Performance and SEO analysis\u003C/span>\n  \u003Cspan class=\"hljs-attr\">performance-analysis:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;Performance &amp; SEO Analysis&#x27;\u003C/span>\n    \u003Cspan class=\"hljs-attr\">runs-on:\u003C/span> \u003Cspan class=\"hljs-string\">ubuntu-latest\u003C/span>\n    \u003Cspan class=\"hljs-attr\">needs:\u003C/span> \u003Cspan class=\"hljs-string\">build-documentation\u003C/span>\n    \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">github.event_name\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;push&#x27;\u003C/span> \u003Cspan class=\"hljs-string\">&amp;&amp;\u003C/span> \u003Cspan class=\"hljs-string\">github.ref\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;refs/heads/main&#x27;\u003C/span>\n    \n    \u003Cspan class=\"hljs-attr\">steps:\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Checkout\u003C/span> \u003Cspan class=\"hljs-string\">repository\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/checkout@v4\u003C/span>\n        \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Download\u003C/span> \u003Cspan class=\"hljs-string\">build\u003C/span> \u003Cspan class=\"hljs-string\">artifacts\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/download-artifact@v3\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">built-site-jekyll\u003C/span>\n          \u003Cspan class=\"hljs-attr\">path:\u003C/span> \u003Cspan class=\"hljs-string\">_site/\u003C/span>\n          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Setup\u003C/span> \u003Cspan class=\"hljs-string\">Node.js\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/setup-node@v3\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">node-version:\u003C/span> \u003Cspan class=\"hljs-string\">${{\u003C/span> \u003Cspan class=\"hljs-string\">env.NODE_VERSION\u003C/span> \u003Cspan class=\"hljs-string\">}}\u003C/span>\n          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Install\u003C/span> \u003Cspan class=\"hljs-string\">Lighthouse\u003C/span> \u003Cspan class=\"hljs-string\">CI\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          npm install -g @lhci/cli@0.12.x\n\u003C/span>          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Start\u003C/span> \u003Cspan class=\"hljs-string\">test\u003C/span> \u003Cspan class=\"hljs-string\">server\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          cd _site\n          python3 -m http.server 8080 &amp;\n          sleep 5\n\u003C/span>          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Run\u003C/span> \u003Cspan class=\"hljs-string\">Lighthouse\u003C/span> \u003Cspan class=\"hljs-string\">CI\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          lhci autorun --upload.target=temporary-public-storage --collect.url=http://localhost:8080\n\u003C/span>          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">SEO\u003C/span> \u003Cspan class=\"hljs-string\">analysis\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          # Install SEO analysis tools\n          npm install -g seo-analyzer\n\u003C/span>          \n          \u003Cspan class=\"hljs-comment\"># Analyze built site\u003C/span>\n          \u003Cspan class=\"hljs-string\">find\u003C/span> \u003Cspan class=\"hljs-string\">_site\u003C/span> \u003Cspan class=\"hljs-string\">-name\u003C/span> \u003Cspan class=\"hljs-string\">&quot;*.html&quot;\u003C/span> \u003Cspan class=\"hljs-string\">-type\u003C/span> \u003Cspan class=\"hljs-string\">f\u003C/span> \u003Cspan class=\"hljs-string\">|\u003C/span> \u003Cspan class=\"hljs-string\">head\u003C/span> \u003Cspan class=\"hljs-number\">-10\u003C/span> \u003Cspan class=\"hljs-string\">|\u003C/span> \u003Cspan class=\"hljs-string\">xargs\u003C/span> \u003Cspan class=\"hljs-string\">-I\u003C/span> {} \u003Cspan class=\"hljs-string\">\\\u003C/span>\n          \u003Cspan class=\"hljs-string\">node\u003C/span> \u003Cspan class=\"hljs-string\">-e\u003C/span> \u003Cspan class=\"hljs-string\">&quot;\n            const seo = require(&#x27;seo-analyzer&#x27;);\n            const fs = require(&#x27;fs&#x27;);\n            const file = &#x27;{}&#x27;;\n            const content = fs.readFileSync(file, &#x27;utf8&#x27;);\n            seo.analyze(content, { headings: true, meta: true, links: true })\n              .then(result =&gt; console.log(JSON.stringify({file, result}, null, 2)));\n          &quot;\u003C/span> \u003Cspan class=\"hljs-string\">&gt;\u003C/span> \u003Cspan class=\"hljs-string\">seo-analysis-report.json\u003C/span>\n\n  \u003Cspan class=\"hljs-comment\"># Automated deployment\u003C/span>\n  \u003Cspan class=\"hljs-attr\">deploy-staging:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;Deploy to Staging&#x27;\u003C/span>\n    \u003Cspan class=\"hljs-attr\">runs-on:\u003C/span> \u003Cspan class=\"hljs-string\">ubuntu-latest\u003C/span>\n    \u003Cspan class=\"hljs-attr\">needs:\u003C/span> [\u003Cspan class=\"hljs-string\">content-validation\u003C/span>, \u003Cspan class=\"hljs-string\">build-documentation\u003C/span>, \u003Cspan class=\"hljs-string\">security-scan\u003C/span>]\n    \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">github.ref\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;refs/heads/develop&#x27;\u003C/span> \u003Cspan class=\"hljs-string\">||\u003C/span> \u003Cspan class=\"hljs-string\">github.event.inputs.deploy_environment\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;staging&#x27;\u003C/span>\n    \u003Cspan class=\"hljs-attr\">environment:\u003C/span>\n      \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">staging\u003C/span>\n      \u003Cspan class=\"hljs-attr\">url:\u003C/span> \u003Cspan class=\"hljs-string\">https://staging.markdowntools.com\u003C/span>\n      \n    \u003Cspan class=\"hljs-attr\">steps:\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Checkout\u003C/span> \u003Cspan class=\"hljs-string\">repository\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/checkout@v4\u003C/span>\n        \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Download\u003C/span> \u003Cspan class=\"hljs-string\">build\u003C/span> \u003Cspan class=\"hljs-string\">artifacts\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/download-artifact@v3\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">built-site-jekyll\u003C/span>\n          \u003Cspan class=\"hljs-attr\">path:\u003C/span> \u003Cspan class=\"hljs-string\">_site/\u003C/span>\n          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Deploy\u003C/span> \u003Cspan class=\"hljs-string\">to\u003C/span> \u003Cspan class=\"hljs-string\">staging\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">peaceiris/actions-gh-pages@v3\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">github_token:\u003C/span> \u003Cspan class=\"hljs-string\">${{\u003C/span> \u003Cspan class=\"hljs-string\">secrets.GITHUB_TOKEN\u003C/span> \u003Cspan class=\"hljs-string\">}}\u003C/span>\n          \u003Cspan class=\"hljs-attr\">publish_dir:\u003C/span> \u003Cspan class=\"hljs-string\">./_site\u003C/span>\n          \u003Cspan class=\"hljs-attr\">publish_branch:\u003C/span> \u003Cspan class=\"hljs-string\">gh-pages-staging\u003C/span>\n          \u003Cspan class=\"hljs-attr\">cname:\u003C/span> \u003Cspan class=\"hljs-string\">staging.markdowntools.com\u003C/span>\n          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Notify\u003C/span> \u003Cspan class=\"hljs-string\">deployment\u003C/span> \u003Cspan class=\"hljs-string\">success\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">8398a7/action-slack@v3\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">status:\u003C/span> \u003Cspan class=\"hljs-string\">success\u003C/span>\n          \u003Cspan class=\"hljs-attr\">channel:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;#deployments&#x27;\u003C/span>\n          \u003Cspan class=\"hljs-attr\">webhook_url:\u003C/span> \u003Cspan class=\"hljs-string\">${{\u003C/span> \u003Cspan class=\"hljs-string\">secrets.SLACK_WEBHOOK\u003C/span> \u003Cspan class=\"hljs-string\">}}\u003C/span>\n\n  \u003Cspan class=\"hljs-attr\">deploy-production:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;Deploy to Production&#x27;\u003C/span>\n    \u003Cspan class=\"hljs-attr\">runs-on:\u003C/span> \u003Cspan class=\"hljs-string\">ubuntu-latest\u003C/span>\n    \u003Cspan class=\"hljs-attr\">needs:\u003C/span> [\u003Cspan class=\"hljs-string\">content-validation\u003C/span>, \u003Cspan class=\"hljs-string\">build-documentation\u003C/span>, \u003Cspan class=\"hljs-string\">security-scan\u003C/span>, \u003Cspan class=\"hljs-string\">performance-analysis\u003C/span>]\n    \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">github.ref\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;refs/heads/main&#x27;\u003C/span> \u003Cspan class=\"hljs-string\">||\u003C/span> \u003Cspan class=\"hljs-string\">github.event.inputs.deploy_environment\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;production&#x27;\u003C/span>\n    \u003Cspan class=\"hljs-attr\">environment:\u003C/span>\n      \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">production\u003C/span>\n      \u003Cspan class=\"hljs-attr\">url:\u003C/span> \u003Cspan class=\"hljs-string\">https://blog.markdowntools.com\u003C/span>\n      \n    \u003Cspan class=\"hljs-attr\">steps:\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Checkout\u003C/span> \u003Cspan class=\"hljs-string\">repository\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/checkout@v4\u003C/span>\n        \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Download\u003C/span> \u003Cspan class=\"hljs-string\">build\u003C/span> \u003Cspan class=\"hljs-string\">artifacts\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/download-artifact@v3\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">built-site-jekyll\u003C/span>\n          \u003Cspan class=\"hljs-attr\">path:\u003C/span> \u003Cspan class=\"hljs-string\">_site/\u003C/span>\n          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Deploy\u003C/span> \u003Cspan class=\"hljs-string\">to\u003C/span> \u003Cspan class=\"hljs-string\">production\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">peaceiris/actions-gh-pages@v3\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">github_token:\u003C/span> \u003Cspan class=\"hljs-string\">${{\u003C/span> \u003Cspan class=\"hljs-string\">secrets.GITHUB_TOKEN\u003C/span> \u003Cspan class=\"hljs-string\">}}\u003C/span>\n          \u003Cspan class=\"hljs-attr\">publish_dir:\u003C/span> \u003Cspan class=\"hljs-string\">./_site\u003C/span>\n          \u003Cspan class=\"hljs-attr\">publish_branch:\u003C/span> \u003Cspan class=\"hljs-string\">gh-pages\u003C/span>\n          \u003Cspan class=\"hljs-attr\">cname:\u003C/span> \u003Cspan class=\"hljs-string\">blog.markdowntools.com\u003C/span>\n          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Purge\u003C/span> \u003Cspan class=\"hljs-string\">CDN\u003C/span> \u003Cspan class=\"hljs-string\">cache\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          # Purge CloudFlare cache\n          curl -X POST &quot;https://api.cloudflare.com/client/v4/zones/${{ secrets.CLOUDFLARE_ZONE_ID }}/purge_cache&quot; \\\n            -H &quot;Authorization: Bearer ${{ secrets.CLOUDFLARE_TOKEN }}&quot; \\\n            -H &quot;Content-Type: application/json&quot; \\\n            --data &#x27;{&quot;purge_everything&quot;:true}&#x27;\n            \n\u003C/span>      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Update\u003C/span> \u003Cspan class=\"hljs-string\">search\u003C/span> \u003Cspan class=\"hljs-string\">index\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          # Update Algolia search index\n          curl -X POST &quot;${{ secrets.ALGOLIA_WEBHOOK_URL }}&quot; \\\n            -H &quot;Authorization: Bearer ${{ secrets.ALGOLIA_API_KEY }}&quot;\n            \n\u003C/span>      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Notify\u003C/span> \u003Cspan class=\"hljs-string\">deployment\u003C/span> \u003Cspan class=\"hljs-string\">success\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">8398a7/action-slack@v3\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">status:\u003C/span> \u003Cspan class=\"hljs-string\">success\u003C/span>\n          \u003Cspan class=\"hljs-attr\">channel:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;#deployments&#x27;\u003C/span>\n          \u003Cspan class=\"hljs-attr\">webhook_url:\u003C/span> \u003Cspan class=\"hljs-string\">${{\u003C/span> \u003Cspan class=\"hljs-string\">secrets.SLACK_WEBHOOK\u003C/span> \u003Cspan class=\"hljs-string\">}}\u003C/span>\n          \u003Cspan class=\"hljs-attr\">custom_payload:\u003C/span> \u003Cspan class=\"hljs-string\">|\n            {\n              text: &quot;Production deployment successful! 🚀&quot;,\n              attachments: [{\n                color: &#x27;good&#x27;,\n                fields: [{\n                  title: &#x27;Environment&#x27;,\n                  value: &#x27;Production&#x27;,\n                  short: true\n                }, {\n                  title: &#x27;URL&#x27;,\n                  value: &#x27;https://blog.markdowntools.com&#x27;,\n                  short: true\n                }]\n              }]\n            }\n\u003C/span>\n  \u003Cspan class=\"hljs-comment\"># Content analytics and reporting\u003C/span>\n  \u003Cspan class=\"hljs-attr\">analytics-reporting:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;Analytics &amp; Reporting&#x27;\u003C/span>\n    \u003Cspan class=\"hljs-attr\">runs-on:\u003C/span> \u003Cspan class=\"hljs-string\">ubuntu-latest\u003C/span>\n    \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">github.event_name\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;schedule&#x27;\u003C/span>\n    \n    \u003Cspan class=\"hljs-attr\">steps:\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Checkout\u003C/span> \u003Cspan class=\"hljs-string\">repository\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/checkout@v4\u003C/span>\n        \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Setup\u003C/span> \u003Cspan class=\"hljs-string\">Python\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/setup-python@v4\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">python-version:\u003C/span> \u003Cspan class=\"hljs-string\">${{\u003C/span> \u003Cspan class=\"hljs-string\">env.PYTHON_VERSION\u003C/span> \u003Cspan class=\"hljs-string\">}}\u003C/span>\n          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Install\u003C/span> \u003Cspan class=\"hljs-string\">analytics\u003C/span> \u003Cspan class=\"hljs-string\">dependencies\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          pip install google-analytics-reporting-api\n          pip install markdown-metrics\n          pip install git-stats\n\u003C/span>          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Generate\u003C/span> \u003Cspan class=\"hljs-string\">content\u003C/span> \u003Cspan class=\"hljs-string\">analytics\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          python3 scripts/generate-content-analytics.py\n\u003C/span>          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Create\u003C/span> \u003Cspan class=\"hljs-string\">weekly\u003C/span> \u003Cspan class=\"hljs-string\">report\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          python3 scripts/generate-weekly-report.py\n\u003C/span>          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Send\u003C/span> \u003Cspan class=\"hljs-string\">report\u003C/span> \u003Cspan class=\"hljs-string\">via\u003C/span> \u003Cspan class=\"hljs-string\">email\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">dawidd6/action-send-mail@v3\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">server_address:\u003C/span> \u003Cspan class=\"hljs-string\">smtp.gmail.com\u003C/span>\n          \u003Cspan class=\"hljs-attr\">server_port:\u003C/span> \u003Cspan class=\"hljs-number\">587\u003C/span>\n          \u003Cspan class=\"hljs-attr\">username:\u003C/span> \u003Cspan class=\"hljs-string\">${{\u003C/span> \u003Cspan class=\"hljs-string\">secrets.SMTP_USERNAME\u003C/span> \u003Cspan class=\"hljs-string\">}}\u003C/span>\n          \u003Cspan class=\"hljs-attr\">password:\u003C/span> \u003Cspan class=\"hljs-string\">${{\u003C/span> \u003Cspan class=\"hljs-string\">secrets.SMTP_PASSWORD\u003C/span> \u003Cspan class=\"hljs-string\">}}\u003C/span>\n          \u003Cspan class=\"hljs-attr\">subject:\u003C/span> \u003Cspan class=\"hljs-string\">Weekly\u003C/span> \u003Cspan class=\"hljs-string\">Content\u003C/span> \u003Cspan class=\"hljs-string\">Analytics\u003C/span> \u003Cspan class=\"hljs-string\">Report\u003C/span>\n          \u003Cspan class=\"hljs-attr\">to:\u003C/span> \u003Cspan class=\"hljs-string\">team@markdowntools.com\u003C/span>\n          \u003Cspan class=\"hljs-attr\">from:\u003C/span> \u003Cspan class=\"hljs-string\">automation@markdowntools.com\u003C/span>\n          \u003Cspan class=\"hljs-attr\">html_body:\u003C/span> \u003Cspan class=\"hljs-string\">file://weekly-report.html\u003C/span>\n          \u003Cspan class=\"hljs-attr\">attachments:\u003C/span> \u003Cspan class=\"hljs-string\">weekly-analytics.csv\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch3 id=\"content-validation-scripts\">Content Validation Scripts\u003C/h3>\n\u003Cp>Automated content quality assurance through custom validation:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-python\">\u003Cspan class=\"hljs-comment\"># scripts/validate-content-structure.py - Content validation automation\u003C/span>\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> os\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> re\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> yaml\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> json\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> sys\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> pathlib \u003Cspan class=\"hljs-keyword\">import\u003C/span> Path\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> datetime \u003Cspan class=\"hljs-keyword\">import\u003C/span> datetime, timedelta\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> collections \u003Cspan class=\"hljs-keyword\">import\u003C/span> defaultdict\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">MarkdownContentValidator\u003C/span>:\n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">__init__\u003C/span>(\u003Cspan class=\"hljs-params\">self, content_directory=\u003Cspan class=\"hljs-string\">&quot;_posts&quot;\u003C/span>, config_file=\u003Cspan class=\"hljs-literal\">None\u003C/span>\u003C/span>):\n        self.content_directory = Path(content_directory)\n        self.config = self.load_config(config_file)\n        self.errors = []\n        self.warnings = []\n        self.stats = defaultdict(\u003Cspan class=\"hljs-built_in\">int\u003C/span>)\n        \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">load_config\u003C/span>(\u003Cspan class=\"hljs-params\">self, config_file\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Load validation configuration&quot;&quot;&quot;\u003C/span>\n        default_config = {\n            \u003Cspan class=\"hljs-string\">&quot;required_frontmatter&quot;\u003C/span>: [\u003Cspan class=\"hljs-string\">&quot;title&quot;\u003C/span>, \u003Cspan class=\"hljs-string\">&quot;description&quot;\u003C/span>, \u003Cspan class=\"hljs-string\">&quot;date&quot;\u003C/span>, \u003Cspan class=\"hljs-string\">&quot;author&quot;\u003C/span>, \u003Cspan class=\"hljs-string\">&quot;layout&quot;\u003C/span>],\n            \u003Cspan class=\"hljs-string\">&quot;max_title_length&quot;\u003C/span>: \u003Cspan class=\"hljs-number\">120\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&quot;min_description_length&quot;\u003C/span>: \u003Cspan class=\"hljs-number\">50\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&quot;max_description_length&quot;\u003C/span>: \u003Cspan class=\"hljs-number\">300\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&quot;required_categories&quot;\u003C/span>: [\u003Cspan class=\"hljs-string\">&quot;Tutorial&quot;\u003C/span>, \u003Cspan class=\"hljs-string\">&quot;Guide&quot;\u003C/span>, \u003Cspan class=\"hljs-string\">&quot;Reference&quot;\u003C/span>],\n            \u003Cspan class=\"hljs-string\">&quot;content_rules&quot;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&quot;min_word_count&quot;\u003C/span>: \u003Cspan class=\"hljs-number\">500\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&quot;max_word_count&quot;\u003C/span>: \u003Cspan class=\"hljs-number\">10000\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&quot;require_headings&quot;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&quot;require_code_examples&quot;\u003C/span>: \u003Cspan class=\"hljs-literal\">False\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&quot;max_heading_depth&quot;\u003C/span>: \u003Cspan class=\"hljs-number\">4\u003C/span>\n            },\n            \u003Cspan class=\"hljs-string\">&quot;link_validation&quot;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&quot;check_internal_links&quot;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&quot;check_external_links&quot;\u003C/span>: \u003Cspan class=\"hljs-literal\">False\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&quot;allowed_domains&quot;\u003C/span>: [\u003Cspan class=\"hljs-string\">&quot;blog.markdowntools.com&quot;\u003C/span>],\n                \u003Cspan class=\"hljs-string\">&quot;require_https&quot;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>\n            },\n            \u003Cspan class=\"hljs-string\">&quot;image_validation&quot;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&quot;check_alt_text&quot;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&quot;max_file_size_mb&quot;\u003C/span>: \u003Cspan class=\"hljs-number\">2\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&quot;allowed_formats&quot;\u003C/span>: [\u003Cspan class=\"hljs-string\">&quot;.jpg&quot;\u003C/span>, \u003Cspan class=\"hljs-string\">&quot;.jpeg&quot;\u003C/span>, \u003Cspan class=\"hljs-string\">&quot;.png&quot;\u003C/span>, \u003Cspan class=\"hljs-string\">&quot;.webp&quot;\u003C/span>, \u003Cspan class=\"hljs-string\">&quot;.svg&quot;\u003C/span>]\n            }\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> config_file \u003Cspan class=\"hljs-keyword\">and\u003C/span> Path(config_file).exists():\n            \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(config_file, \u003Cspan class=\"hljs-string\">&#x27;r&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n                custom_config = yaml.safe_load(f)\n                default_config.update(custom_config)\n                \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> default_config\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_all_content\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate all markdown files in the content directory&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;Starting validation of content in \u003Cspan class=\"hljs-subst\">{self.content_directory}\u003C/span>&quot;\u003C/span>)\n        \n        markdown_files = \u003Cspan class=\"hljs-built_in\">list\u003C/span>(self.content_directory.glob(\u003Cspan class=\"hljs-string\">&quot;*.md&quot;\u003C/span>))\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> markdown_files:\n            self.errors.append(\u003Cspan class=\"hljs-string\">&quot;No markdown files found in content directory&quot;\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">False\u003C/span>\n            \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> file_path \u003Cspan class=\"hljs-keyword\">in\u003C/span> markdown_files:\n            \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;Validating: \u003Cspan class=\"hljs-subst\">{file_path.name}\u003C/span>&quot;\u003C/span>)\n            self.validate_file(file_path)\n            \n        self.generate_validation_summary()\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(self.errors) == \u003Cspan class=\"hljs-number\">0\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_file\u003C/span>(\u003Cspan class=\"hljs-params\">self, file_path\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate a single markdown file&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n            \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(file_path, \u003Cspan class=\"hljs-string\">&#x27;r&#x27;\u003C/span>, encoding=\u003Cspan class=\"hljs-string\">&#x27;utf-8&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n                content = f.read()\n                \n            \u003Cspan class=\"hljs-comment\"># Parse frontmatter and content\u003C/span>\n            frontmatter, body = self.parse_frontmatter(content)\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> frontmatter:\n                self.errors.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{file_path.name}\u003C/span>: Missing frontmatter&quot;\u003C/span>)\n                \u003Cspan class=\"hljs-keyword\">return\u003C/span>\n                \n            \u003Cspan class=\"hljs-comment\"># Validate frontmatter\u003C/span>\n            self.validate_frontmatter(file_path.name, frontmatter)\n            \n            \u003Cspan class=\"hljs-comment\"># Validate content structure\u003C/span>\n            self.validate_content_structure(file_path.name, body)\n            \n            \u003Cspan class=\"hljs-comment\"># Validate links and images\u003C/span>\n            self.validate_links_and_images(file_path.name, body)\n            \n            \u003Cspan class=\"hljs-comment\"># Update statistics\u003C/span>\n            self.update_statistics(frontmatter, body)\n            \n        \u003Cspan class=\"hljs-keyword\">except\u003C/span> Exception \u003Cspan class=\"hljs-keyword\">as\u003C/span> e:\n            self.errors.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{file_path.name}\u003C/span>: Error reading file - \u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">str\u003C/span>(e)}\u003C/span>&quot;\u003C/span>)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">parse_frontmatter\u003C/span>(\u003Cspan class=\"hljs-params\">self, content\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Parse YAML frontmatter from markdown content&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> content.startswith(\u003Cspan class=\"hljs-string\">&#x27;---&#x27;\u003C/span>):\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">None\u003C/span>, content\n            \n        \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n            parts = content.split(\u003Cspan class=\"hljs-string\">&#x27;---&#x27;\u003C/span>, \u003Cspan class=\"hljs-number\">2\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(parts) &lt; \u003Cspan class=\"hljs-number\">3\u003C/span>:\n                \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">None\u003C/span>, content\n                \n            frontmatter = yaml.safe_load(parts[\u003Cspan class=\"hljs-number\">1\u003C/span>])\n            body = parts[\u003Cspan class=\"hljs-number\">2\u003C/span>].strip()\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> frontmatter, body\n            \n        \u003Cspan class=\"hljs-keyword\">except\u003C/span> yaml.YAMLError \u003Cspan class=\"hljs-keyword\">as\u003C/span> e:\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">None\u003C/span>, content\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_frontmatter\u003C/span>(\u003Cspan class=\"hljs-params\">self, filename, frontmatter\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate frontmatter fields&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-comment\"># Check required fields\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> field \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.config[\u003Cspan class=\"hljs-string\">&quot;required_frontmatter&quot;\u003C/span>]:\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> field \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> frontmatter:\n                self.errors.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{filename}\u003C/span>: Missing required field &#x27;\u003Cspan class=\"hljs-subst\">{field}\u003C/span>&#x27;&quot;\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">elif\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> frontmatter[field]:\n                self.errors.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{filename}\u003C/span>: Empty required field &#x27;\u003Cspan class=\"hljs-subst\">{field}\u003C/span>&#x27;&quot;\u003C/span>)\n                \n        \u003Cspan class=\"hljs-comment\"># Validate title\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&quot;title&quot;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> frontmatter:\n            title = frontmatter[\u003Cspan class=\"hljs-string\">&quot;title&quot;\u003C/span>]\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(title) &gt; self.config[\u003Cspan class=\"hljs-string\">&quot;max_title_length&quot;\u003C/span>]:\n                self.warnings.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{filename}\u003C/span>: Title too long (\u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">len\u003C/span>(title)}\u003C/span> chars)&quot;\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> title[\u003Cspan class=\"hljs-number\">0\u003C/span>].isupper():\n                self.warnings.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{filename}\u003C/span>: Title should start with uppercase letter&quot;\u003C/span>)\n                \n        \u003Cspan class=\"hljs-comment\"># Validate description\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&quot;description&quot;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> frontmatter:\n            desc = frontmatter[\u003Cspan class=\"hljs-string\">&quot;description&quot;\u003C/span>]\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(desc) &lt; self.config[\u003Cspan class=\"hljs-string\">&quot;min_description_length&quot;\u003C/span>]:\n                self.warnings.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{filename}\u003C/span>: Description too short (\u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">len\u003C/span>(desc)}\u003C/span> chars)&quot;\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">elif\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(desc) &gt; self.config[\u003Cspan class=\"hljs-string\">&quot;max_description_length&quot;\u003C/span>]:\n                self.warnings.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{filename}\u003C/span>: Description too long (\u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">len\u003C/span>(desc)}\u003C/span> chars)&quot;\u003C/span>)\n                \n        \u003Cspan class=\"hljs-comment\"># Validate date format\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&quot;date&quot;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> frontmatter:\n            date_str = \u003Cspan class=\"hljs-built_in\">str\u003C/span>(frontmatter[\u003Cspan class=\"hljs-string\">&quot;date&quot;\u003C/span>])\n            \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n                datetime.strptime(date_str, \u003Cspan class=\"hljs-string\">&quot;%Y-%m-%d&quot;\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">except\u003C/span> ValueError:\n                self.errors.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{filename}\u003C/span>: Invalid date format &#x27;\u003Cspan class=\"hljs-subst\">{date_str}\u003C/span>&#x27; (use YYYY-MM-DD)&quot;\u003C/span>)\n                \n        \u003Cspan class=\"hljs-comment\"># Validate category\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&quot;category&quot;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> frontmatter:\n            category = frontmatter[\u003Cspan class=\"hljs-string\">&quot;category&quot;\u003C/span>]\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> category \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.config[\u003Cspan class=\"hljs-string\">&quot;required_categories&quot;\u003C/span>]:\n                self.warnings.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{filename}\u003C/span>: Category &#x27;\u003Cspan class=\"hljs-subst\">{category}\u003C/span>&#x27; not in approved list&quot;\u003C/span>)\n                \n        \u003Cspan class=\"hljs-comment\"># Validate keywords\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&quot;keywords&quot;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> frontmatter:\n            keywords = frontmatter[\u003Cspan class=\"hljs-string\">&quot;keywords&quot;\u003C/span>]\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">isinstance\u003C/span>(keywords, \u003Cspan class=\"hljs-built_in\">str\u003C/span>):\n                keyword_count = \u003Cspan class=\"hljs-built_in\">len\u003C/span>([k.strip() \u003Cspan class=\"hljs-keyword\">for\u003C/span> k \u003Cspan class=\"hljs-keyword\">in\u003C/span> keywords.split(\u003Cspan class=\"hljs-string\">&quot;,&quot;\u003C/span>) \u003Cspan class=\"hljs-keyword\">if\u003C/span> k.strip()])\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> keyword_count &lt; \u003Cspan class=\"hljs-number\">3\u003C/span>:\n                    self.warnings.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{filename}\u003C/span>: Too few keywords (\u003Cspan class=\"hljs-subst\">{keyword_count}\u003C/span>)&quot;\u003C/span>)\n                \u003Cspan class=\"hljs-keyword\">elif\u003C/span> keyword_count &gt; \u003Cspan class=\"hljs-number\">15\u003C/span>:\n                    self.warnings.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{filename}\u003C/span>: Too many keywords (\u003Cspan class=\"hljs-subst\">{keyword_count}\u003C/span>)&quot;\u003C/span>)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_content_structure\u003C/span>(\u003Cspan class=\"hljs-params\">self, filename, body\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate markdown content structure&quot;&quot;&quot;\u003C/span>\n        rules = self.config[\u003Cspan class=\"hljs-string\">&quot;content_rules&quot;\u003C/span>]\n        \n        \u003Cspan class=\"hljs-comment\"># Word count validation\u003C/span>\n        word_count = \u003Cspan class=\"hljs-built_in\">len\u003C/span>(body.split())\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> word_count &lt; rules[\u003Cspan class=\"hljs-string\">&quot;min_word_count&quot;\u003C/span>]:\n            self.warnings.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{filename}\u003C/span>: Content too short (\u003Cspan class=\"hljs-subst\">{word_count}\u003C/span> words)&quot;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">elif\u003C/span> word_count &gt; rules[\u003Cspan class=\"hljs-string\">&quot;max_word_count&quot;\u003C/span>]:\n            self.warnings.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{filename}\u003C/span>: Content too long (\u003Cspan class=\"hljs-subst\">{word_count}\u003C/span> words)&quot;\u003C/span>)\n            \n        \u003Cspan class=\"hljs-comment\"># Heading validation\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> rules[\u003Cspan class=\"hljs-string\">&quot;require_headings&quot;\u003C/span>]:\n            headings = re.findall(\u003Cspan class=\"hljs-string\">r&#x27;^(#{1,6})\\s+(.+)$&#x27;\u003C/span>, body, re.MULTILINE)\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> headings:\n                self.errors.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{filename}\u003C/span>: No headings found&quot;\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n                \u003Cspan class=\"hljs-comment\"># Check heading hierarchy\u003C/span>\n                prev_level = \u003Cspan class=\"hljs-number\">0\u003C/span>\n                \u003Cspan class=\"hljs-keyword\">for\u003C/span> heading \u003Cspan class=\"hljs-keyword\">in\u003C/span> headings:\n                    level = \u003Cspan class=\"hljs-built_in\">len\u003C/span>(heading[\u003Cspan class=\"hljs-number\">0\u003C/span>])\n                    \u003Cspan class=\"hljs-keyword\">if\u003C/span> level &gt; rules[\u003Cspan class=\"hljs-string\">&quot;max_heading_depth&quot;\u003C/span>]:\n                        self.warnings.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{filename}\u003C/span>: Heading too deep (level \u003Cspan class=\"hljs-subst\">{level}\u003C/span>)&quot;\u003C/span>)\n                    \u003Cspan class=\"hljs-keyword\">if\u003C/span> level &gt; prev_level + \u003Cspan class=\"hljs-number\">1\u003C/span>:\n                        self.warnings.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{filename}\u003C/span>: Skipped heading level (from h\u003Cspan class=\"hljs-subst\">{prev_level}\u003C/span> to h\u003Cspan class=\"hljs-subst\">{level}\u003C/span>)&quot;\u003C/span>)\n                    prev_level = level\n                    \n        \u003Cspan class=\"hljs-comment\"># Code block validation\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> rules[\u003Cspan class=\"hljs-string\">&quot;require_code_examples&quot;\u003C/span>]:\n            code_blocks = re.findall(\u003Cspan class=\"hljs-string\">r&#x27;```[\\s\\S]*?```&#x27;\u003C/span>, body)\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> code_blocks:\n                self.warnings.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{filename}\u003C/span>: No code examples found&quot;\u003C/span>)\n                \n        \u003Cspan class=\"hljs-comment\"># Check for proper markdown syntax\u003C/span>\n        self.validate_markdown_syntax(filename, body)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_markdown_syntax\u003C/span>(\u003Cspan class=\"hljs-params\">self, filename, body\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate markdown syntax correctness&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-comment\"># Check for unmatched code blocks\u003C/span>\n        code_block_starts = body.count(\u003Cspan class=\"hljs-string\">&#x27;```&#x27;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> code_block_starts % \u003Cspan class=\"hljs-number\">2\u003C/span> != \u003Cspan class=\"hljs-number\">0\u003C/span>:\n            self.errors.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{filename}\u003C/span>: Unmatched code block delimiters&quot;\u003C/span>)\n            \n        \u003Cspan class=\"hljs-comment\"># Check for proper link syntax\u003C/span>\n        malformed_links = re.findall(\u003Cspan class=\"hljs-string\">r&#x27;\\[([^\\]]+)\\]\\s*\\([^)]*$&#x27;\u003C/span>, body, re.MULTILINE)\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> malformed_links:\n            self.errors.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{filename}\u003C/span>: Malformed links found&quot;\u003C/span>)\n            \n        \u003Cspan class=\"hljs-comment\"># Check for nested code blocks in examples\u003C/span>\n        nested_code_pattern = \u003Cspan class=\"hljs-string\">r&#x27;```[\\s\\S]*?```[\\s\\S]*?```[\\s\\S]*?```&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> re.search(nested_code_pattern, body):\n            \u003Cspan class=\"hljs-comment\"># Check if {% raw %} tags are used\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;{% raw %}&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> body \u003Cspan class=\"hljs-keyword\">or\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;{% endraw %}&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> body:\n                self.warnings.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{filename}\u003C/span>: Nested code blocks without \u003Cspan class=\"hljs-subst\">{% raw %}\u003C/span> tags&quot;\u003C/span>)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_links_and_images\u003C/span>(\u003Cspan class=\"hljs-params\">self, filename, body\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate links and images in content&quot;&quot;&quot;\u003C/span>\n        link_config = self.config[\u003Cspan class=\"hljs-string\">&quot;link_validation&quot;\u003C/span>]\n        image_config = self.config[\u003Cspan class=\"hljs-string\">&quot;image_validation&quot;\u003C/span>]\n        \n        \u003Cspan class=\"hljs-comment\"># Find all links\u003C/span>\n        links = re.findall(\u003Cspan class=\"hljs-string\">r&#x27;\\[([^\\]]+)\\]\\(([^)]+)\\)&#x27;\u003C/span>, body)\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> link_text, link_url \u003Cspan class=\"hljs-keyword\">in\u003C/span> links:\n            \u003Cspan class=\"hljs-comment\"># Check internal links\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> link_config[\u003Cspan class=\"hljs-string\">&quot;check_internal_links&quot;\u003C/span>] \u003Cspan class=\"hljs-keyword\">and\u003C/span> link_url.startswith(\u003Cspan class=\"hljs-string\">&#x27;/&#x27;\u003C/span>):\n                \u003Cspan class=\"hljs-comment\"># This would need actual file system checking\u003C/span>\n                \u003Cspan class=\"hljs-keyword\">pass\u003C/span>\n                \n            \u003Cspan class=\"hljs-comment\"># Check HTTPS requirement\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> link_config[\u003Cspan class=\"hljs-string\">&quot;require_https&quot;\u003C/span>] \u003Cspan class=\"hljs-keyword\">and\u003C/span> link_url.startswith(\u003Cspan class=\"hljs-string\">&#x27;http://&#x27;\u003C/span>):\n                self.warnings.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{filename}\u003C/span>: Non-HTTPS link found: \u003Cspan class=\"hljs-subst\">{link_url}\u003C/span>&quot;\u003C/span>)\n                \n        \u003Cspan class=\"hljs-comment\"># Find all images\u003C/span>\n        images = re.findall(\u003Cspan class=\"hljs-string\">r&#x27;!\\[([^\\]]*)\\]\\(([^)]+)\\)&#x27;\u003C/span>, body)\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> alt_text, image_url \u003Cspan class=\"hljs-keyword\">in\u003C/span> images:\n            \u003Cspan class=\"hljs-comment\"># Check alt text\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> image_config[\u003Cspan class=\"hljs-string\">&quot;check_alt_text&quot;\u003C/span>] \u003Cspan class=\"hljs-keyword\">and\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> alt_text.strip():\n                self.warnings.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{filename}\u003C/span>: Image missing alt text: \u003Cspan class=\"hljs-subst\">{image_url}\u003C/span>&quot;\u003C/span>)\n                \n            \u003Cspan class=\"hljs-comment\"># Check file format\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">any\u003C/span>(image_url.lower().endswith(fmt) \u003Cspan class=\"hljs-keyword\">for\u003C/span> fmt \u003Cspan class=\"hljs-keyword\">in\u003C/span> image_config[\u003Cspan class=\"hljs-string\">&quot;allowed_formats&quot;\u003C/span>]):\n                \u003Cspan class=\"hljs-keyword\">continue\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n                self.warnings.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{filename}\u003C/span>: Unsupported image format: \u003Cspan class=\"hljs-subst\">{image_url}\u003C/span>&quot;\u003C/span>)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">update_statistics\u003C/span>(\u003Cspan class=\"hljs-params\">self, frontmatter, body\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Update validation statistics&quot;&quot;&quot;\u003C/span>\n        self.stats[\u003Cspan class=\"hljs-string\">&quot;total_files&quot;\u003C/span>] += \u003Cspan class=\"hljs-number\">1\u003C/span>\n        self.stats[\u003Cspan class=\"hljs-string\">&quot;total_words&quot;\u003C/span>] += \u003Cspan class=\"hljs-built_in\">len\u003C/span>(body.split())\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&quot;category&quot;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> frontmatter:\n            self.stats[\u003Cspan class=\"hljs-string\">f&quot;category_\u003Cspan class=\"hljs-subst\">{frontmatter[\u003Cspan class=\"hljs-string\">&#x27;category&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>] += \u003Cspan class=\"hljs-number\">1\u003C/span>\n            \n        headings = re.findall(\u003Cspan class=\"hljs-string\">r&#x27;^#{1,6}\\s+&#x27;\u003C/span>, body, re.MULTILINE)\n        self.stats[\u003Cspan class=\"hljs-string\">&quot;total_headings&quot;\u003C/span>] += \u003Cspan class=\"hljs-built_in\">len\u003C/span>(headings)\n        \n        code_blocks = re.findall(\u003Cspan class=\"hljs-string\">r&#x27;```[\\s\\S]*?```&#x27;\u003C/span>, body)\n        self.stats[\u003Cspan class=\"hljs-string\">&quot;total_code_blocks&quot;\u003C/span>] += \u003Cspan class=\"hljs-built_in\">len\u003C/span>(code_blocks)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_validation_summary\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Generate validation summary report&quot;&quot;&quot;\u003C/span>\n        summary = {\n            \u003Cspan class=\"hljs-string\">&quot;timestamp&quot;\u003C/span>: datetime.now().isoformat(),\n            \u003Cspan class=\"hljs-string\">&quot;statistics&quot;\u003C/span>: \u003Cspan class=\"hljs-built_in\">dict\u003C/span>(self.stats),\n            \u003Cspan class=\"hljs-string\">&quot;validation_results&quot;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&quot;total_files&quot;\u003C/span>: self.stats[\u003Cspan class=\"hljs-string\">&quot;total_files&quot;\u003C/span>],\n                \u003Cspan class=\"hljs-string\">&quot;errors&quot;\u003C/span>: \u003Cspan class=\"hljs-built_in\">len\u003C/span>(self.errors),\n                \u003Cspan class=\"hljs-string\">&quot;warnings&quot;\u003C/span>: \u003Cspan class=\"hljs-built_in\">len\u003C/span>(self.warnings),\n                \u003Cspan class=\"hljs-string\">&quot;error_details&quot;\u003C/span>: self.errors,\n                \u003Cspan class=\"hljs-string\">&quot;warning_details&quot;\u003C/span>: self.warnings\n            }\n        }\n        \n        \u003Cspan class=\"hljs-comment\"># Write JSON report\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;content-validation-report.json&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;w&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n            json.dump(summary, f, indent=\u003Cspan class=\"hljs-number\">2\u003C/span>)\n            \n        \u003Cspan class=\"hljs-comment\"># Generate HTML report\u003C/span>\n        self.generate_html_report(summary)\n        \n        \u003Cspan class=\"hljs-comment\"># Generate markdown summary for PR comments\u003C/span>\n        self.generate_pr_summary(summary)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_html_report\u003C/span>(\u003Cspan class=\"hljs-params\">self, summary\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Generate HTML validation report&quot;&quot;&quot;\u003C/span>\n        html_template = \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;\n&lt;!DOCTYPE html&gt;\n&lt;html lang=&quot;en&quot;&gt;\n&lt;head&gt;\n    &lt;meta charset=&quot;UTF-8&quot;&gt;\n    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;\n    &lt;title&gt;Content Validation Report&lt;/title&gt;\n    &lt;style&gt;\n        body { font-family: -apple-system, BlinkMacSystemFont, &#x27;Segoe UI&#x27;, sans-serif; margin: 20px; }\n        .header { background: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 20px; }\n        .stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; margin-bottom: 20px; }\n        .stat-card { background: white; border: 1px solid #e9ecef; padding: 15px; border-radius: 8px; }\n        .errors { background: #f8d7da; border-color: #f5c6cb; }\n        .warnings { background: #fff3cd; border-color: #ffeaa7; }\n        .success { background: #d4edda; border-color: #c3e6cb; }\n        .issue-list { margin-top: 10px; }\n        .issue-item { margin: 5px 0; font-family: monospace; font-size: 14px; }\n    &lt;/style&gt;\n&lt;/head&gt;\n&lt;body&gt;\n    &lt;div class=&quot;header&quot;&gt;\n        &lt;h1&gt;Content Validation Report&lt;/h1&gt;\n        &lt;p&gt;Generated on {timestamp}&lt;/p&gt;\n    &lt;/div&gt;\n    \n    &lt;div class=&quot;stats&quot;&gt;\n        &lt;div class=&quot;stat-card&quot;&gt;\n            &lt;h3&gt;Files Processed&lt;/h3&gt;\n            &lt;p style=&quot;font-size: 2em; margin: 0; color: #007bff;&quot;&gt;{total_files}&lt;/p&gt;\n        &lt;/div&gt;\n        &lt;div class=&quot;stat-card {error_class}&quot;&gt;\n            &lt;h3&gt;Errors&lt;/h3&gt;\n            &lt;p style=&quot;font-size: 2em; margin: 0; color: #dc3545;&quot;&gt;{errors}&lt;/p&gt;\n        &lt;/div&gt;\n        &lt;div class=&quot;stat-card {warning_class}&quot;&gt;\n            &lt;h3&gt;Warnings&lt;/h3&gt;\n            &lt;p style=&quot;font-size: 2em; margin: 0; color: #ffc107;&quot;&gt;{warnings}&lt;/p&gt;\n        &lt;/div&gt;\n        &lt;div class=&quot;stat-card&quot;&gt;\n            &lt;h3&gt;Total Words&lt;/h3&gt;\n            &lt;p style=&quot;font-size: 2em; margin: 0; color: #28a745;&quot;&gt;{total_words}&lt;/p&gt;\n        &lt;/div&gt;\n    &lt;/div&gt;\n    \n    {error_section}\n    {warning_section}\n    \n&lt;/body&gt;\n&lt;/html&gt;\n        &quot;&quot;&quot;\u003C/span>.\u003Cspan class=\"hljs-built_in\">format\u003C/span>(\n            timestamp=summary[\u003Cspan class=\"hljs-string\">&quot;timestamp&quot;\u003C/span>],\n            total_files=summary[\u003Cspan class=\"hljs-string\">&quot;statistics&quot;\u003C/span>][\u003Cspan class=\"hljs-string\">&quot;total_files&quot;\u003C/span>],\n            errors=summary[\u003Cspan class=\"hljs-string\">&quot;validation_results&quot;\u003C/span>][\u003Cspan class=\"hljs-string\">&quot;errors&quot;\u003C/span>],\n            warnings=summary[\u003Cspan class=\"hljs-string\">&quot;validation_results&quot;\u003C/span>][\u003Cspan class=\"hljs-string\">&quot;warnings&quot;\u003C/span>],\n            total_words=summary[\u003Cspan class=\"hljs-string\">&quot;statistics&quot;\u003C/span>][\u003Cspan class=\"hljs-string\">&quot;total_words&quot;\u003C/span>],\n            error_class=\u003Cspan class=\"hljs-string\">&quot;errors&quot;\u003C/span> \u003Cspan class=\"hljs-keyword\">if\u003C/span> summary[\u003Cspan class=\"hljs-string\">&quot;validation_results&quot;\u003C/span>][\u003Cspan class=\"hljs-string\">&quot;errors&quot;\u003C/span>] &gt; \u003Cspan class=\"hljs-number\">0\u003C/span> \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-string\">&quot;success&quot;\u003C/span>,\n            warning_class=\u003Cspan class=\"hljs-string\">&quot;warnings&quot;\u003C/span> \u003Cspan class=\"hljs-keyword\">if\u003C/span> summary[\u003Cspan class=\"hljs-string\">&quot;validation_results&quot;\u003C/span>][\u003Cspan class=\"hljs-string\">&quot;warnings&quot;\u003C/span>] &gt; \u003Cspan class=\"hljs-number\">0\u003C/span> \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-string\">&quot;success&quot;\u003C/span>,\n            error_section=self.format_issues_html(\u003Cspan class=\"hljs-string\">&quot;Errors&quot;\u003C/span>, summary[\u003Cspan class=\"hljs-string\">&quot;validation_results&quot;\u003C/span>][\u003Cspan class=\"hljs-string\">&quot;error_details&quot;\u003C/span>]),\n            warning_section=self.format_issues_html(\u003Cspan class=\"hljs-string\">&quot;Warnings&quot;\u003C/span>, summary[\u003Cspan class=\"hljs-string\">&quot;validation_results&quot;\u003C/span>][\u003Cspan class=\"hljs-string\">&quot;warning_details&quot;\u003C/span>])\n        )\n        \n        \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;content-validation-report.html&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;w&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n            f.write(html_template)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">format_issues_html\u003C/span>(\u003Cspan class=\"hljs-params\">self, title, issues\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Format issues for HTML report&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> issues:\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-string\">f&quot;&lt;div class=&#x27;stat-card success&#x27;&gt;&lt;h3&gt;\u003Cspan class=\"hljs-subst\">{title}\u003C/span>&lt;/h3&gt;&lt;p&gt;None found! ✅&lt;/p&gt;&lt;/div&gt;&quot;\u003C/span>\n            \n        issues_html = \u003Cspan class=\"hljs-string\">f&quot;&lt;div class=&#x27;stat-card&#x27;&gt;&lt;h3&gt;\u003Cspan class=\"hljs-subst\">{title}\u003C/span>&lt;/h3&gt;&lt;div class=&#x27;issue-list&#x27;&gt;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> issue \u003Cspan class=\"hljs-keyword\">in\u003C/span> issues:\n            issues_html += \u003Cspan class=\"hljs-string\">f&quot;&lt;div class=&#x27;issue-item&#x27;&gt;• \u003Cspan class=\"hljs-subst\">{issue}\u003C/span>&lt;/div&gt;&quot;\u003C/span>\n        issues_html += \u003Cspan class=\"hljs-string\">&quot;&lt;/div&gt;&lt;/div&gt;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> issues_html\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_pr_summary\u003C/span>(\u003Cspan class=\"hljs-params\">self, summary\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Generate markdown summary for PR comments&quot;&quot;&quot;\u003C/span>\n        pr_summary = \u003Cspan class=\"hljs-string\">f&quot;&quot;&quot;\n## 📝 Content Validation Report\n\n**Files Processed:** \u003Cspan class=\"hljs-subst\">{summary[\u003Cspan class=\"hljs-string\">&#x27;statistics&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;total_files&#x27;\u003C/span>]}\u003C/span>  \n**Errors:** \u003Cspan class=\"hljs-subst\">{summary[\u003Cspan class=\"hljs-string\">&#x27;validation_results&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;errors&#x27;\u003C/span>]}\u003C/span>  \n**Warnings:** \u003Cspan class=\"hljs-subst\">{summary[\u003Cspan class=\"hljs-string\">&#x27;validation_results&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;warnings&#x27;\u003C/span>]}\u003C/span>  \n**Total Words:** \u003Cspan class=\"hljs-subst\">{summary[\u003Cspan class=\"hljs-string\">&#x27;statistics&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;total_words&#x27;\u003C/span>]:,}\u003C/span>\n\n&quot;&quot;&quot;\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> summary[\u003Cspan class=\"hljs-string\">&#x27;validation_results&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;errors&#x27;\u003C/span>] &gt; \u003Cspan class=\"hljs-number\">0\u003C/span>:\n            pr_summary += \u003Cspan class=\"hljs-string\">&quot;### ❌ Errors\\n&quot;\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> error \u003Cspan class=\"hljs-keyword\">in\u003C/span> summary[\u003Cspan class=\"hljs-string\">&#x27;validation_results&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;error_details&#x27;\u003C/span>]:\n                pr_summary += \u003Cspan class=\"hljs-string\">f&quot;- \u003Cspan class=\"hljs-subst\">{error}\u003C/span>\\n&quot;\u003C/span>\n            pr_summary += \u003Cspan class=\"hljs-string\">&quot;\\n&quot;\u003C/span>\n            \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> summary[\u003Cspan class=\"hljs-string\">&#x27;validation_results&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;warnings&#x27;\u003C/span>] &gt; \u003Cspan class=\"hljs-number\">0\u003C/span>:\n            pr_summary += \u003Cspan class=\"hljs-string\">&quot;### ⚠️ Warnings\\n&quot;\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> warning \u003Cspan class=\"hljs-keyword\">in\u003C/span> summary[\u003Cspan class=\"hljs-string\">&#x27;validation_results&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;warning_details&#x27;\u003C/span>]:\n                pr_summary += \u003Cspan class=\"hljs-string\">f&quot;- \u003Cspan class=\"hljs-subst\">{warning}\u003C/span>\\n&quot;\u003C/span>\n            pr_summary += \u003Cspan class=\"hljs-string\">&quot;\\n&quot;\u003C/span>\n            \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> summary[\u003Cspan class=\"hljs-string\">&#x27;validation_results&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;errors&#x27;\u003C/span>] == \u003Cspan class=\"hljs-number\">0\u003C/span> \u003Cspan class=\"hljs-keyword\">and\u003C/span> summary[\u003Cspan class=\"hljs-string\">&#x27;validation_results&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;warnings&#x27;\u003C/span>] == \u003Cspan class=\"hljs-number\">0\u003C/span>:\n            pr_summary += \u003Cspan class=\"hljs-string\">&quot;### ✅ All checks passed!\\n\\nGreat job maintaining content quality standards.\\n&quot;\u003C/span>\n            \n        \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;content-validation-summary.md&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;w&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n            f.write(pr_summary)\n\n\u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">main\u003C/span>():\n    \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Main validation function&quot;&quot;&quot;\u003C/span>\n    validator = MarkdownContentValidator()\n    \n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> validator.validate_all_content():\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">&quot;✅ Content validation passed!&quot;\u003C/span>)\n        sys.exit(\u003Cspan class=\"hljs-number\">0\u003C/span>)\n    \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">&quot;❌ Content validation failed!&quot;\u003C/span>)\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;Errors: \u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">len\u003C/span>(validator.errors)}\u003C/span>&quot;\u003C/span>)\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;Warnings: \u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">len\u003C/span>(validator.warnings)}\u003C/span>&quot;\u003C/span>)\n        sys.exit(\u003Cspan class=\"hljs-number\">1\u003C/span>)\n\n\u003Cspan class=\"hljs-keyword\">if\u003C/span> __name__ == \u003Cspan class=\"hljs-string\">&quot;__main__&quot;\u003C/span>:\n    main()\n\u003C/code>\u003C/pre>\u003Ch2 id=\"advanced-automation-techniques\">Advanced Automation Techniques\u003C/h2>\n\u003Ch3 id=\"dynamic-content-generation\">Dynamic Content Generation\u003C/h3>\n\u003Cp>Automated content creation and updates based on code changes:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-python\">\u003Cspan class=\"hljs-comment\"># scripts/generate-dynamic-content.py - Automated content generation\u003C/span>\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> os\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> json\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> yaml\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> requests\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> datetime \u003Cspan class=\"hljs-keyword\">import\u003C/span> datetime\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> pathlib \u003Cspan class=\"hljs-keyword\">import\u003C/span> Path\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> jinja2 \u003Cspan class=\"hljs-keyword\">import\u003C/span> Template\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> git \u003Cspan class=\"hljs-keyword\">import\u003C/span> Repo\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">DynamicContentGenerator\u003C/span>:\n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">__init__\u003C/span>(\u003Cspan class=\"hljs-params\">self, repo_path=\u003Cspan class=\"hljs-string\">&quot;.&quot;\u003C/span>\u003C/span>):\n        self.repo = Repo(repo_path)\n        self.config = self.load_config()\n        \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">load_config\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Load content generation configuration&quot;&quot;&quot;\u003C/span>\n        config_path = Path(\u003Cspan class=\"hljs-string\">&quot;.github/content-generation.yml&quot;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> config_path.exists():\n            \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(config_path) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n                \u003Cspan class=\"hljs-keyword\">return\u003C/span> yaml.safe_load(f)\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> {}\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_api_documentation\u003C/span>(\u003Cspan class=\"hljs-params\">self, openapi_spec_url\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Generate API documentation from OpenAPI specification&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n            response = requests.get(openapi_spec_url)\n            spec = response.json()\n            \n            template = Template(\u003Cspan class=\"hljs-string\">&quot;&quot;&quot;\n---\ntitle: &quot;{{ spec.info.title }} API Documentation&quot;\ndescription: &quot;{{ spec.info.description }}&quot;\ndate: {{ date }}\nauthor: API Documentation Generator\ncategory: Reference\nlayout: api-doc\n---\n\n# {{ spec.info.title }} API Documentation\n\nVersion: {{ spec.info.version }}\n\n{{ spec.info.description }}\n\n## Endpoints\n\n{% for path, methods in spec.paths.items() %}\n### {{ path }}\n\n{% for method, details in methods.items() %}\n#### {{ method.upper() }} {{ path }}\n\n{{ details.summary | default(&#x27;No summary available&#x27;) }}\n\n**Description:** {{ details.description | default(&#x27;No description available&#x27;) }}\n\n{% if details.parameters %}\n**Parameters:**\n\n| Name | Type | Required | Description |\n|------|------|----------|-------------|\n{% for param in details.parameters %}\n| {{ param.name }} | {{ param.type | default(&#x27;string&#x27;) }} | {{ &#x27;Yes&#x27; if param.required else &#x27;No&#x27; }} | {{ param.description | default(&#x27;&#x27;) }} |\n{% endfor %}\n{% endif %}\n\n{% if details.responses %}\n**Responses:**\n\n{% for code, response in details.responses.items() %}\n- **{{ code }}**: {{ response.description }}\n{% endfor %}\n{% endif %}\n\n{% endfor %}\n{% endfor %}\n&quot;&quot;&quot;\u003C/span>)\n\n            \n            content = template.render(\n                spec=spec,\n                date=datetime.now().strftime(\u003Cspan class=\"hljs-string\">&quot;%Y-%m-%d&quot;\u003C/span>)\n            )\n            \n            output_path = Path(\u003Cspan class=\"hljs-string\">f&quot;_posts/\u003Cspan class=\"hljs-subst\">{datetime.now().strftime(\u003Cspan class=\"hljs-string\">&#x27;%Y-%m-%d&#x27;\u003C/span>)}\u003C/span>-\u003Cspan class=\"hljs-subst\">{spec[\u003Cspan class=\"hljs-string\">&#x27;info&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;title&#x27;\u003C/span>].lower().replace(\u003Cspan class=\"hljs-string\">&#x27; &#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;-&#x27;\u003C/span>)}\u003C/span>-api-documentation.md&quot;\u003C/span>)\n            output_path.write_text(content)\n            \n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> output_path\n            \n        \u003Cspan class=\"hljs-keyword\">except\u003C/span> Exception \u003Cspan class=\"hljs-keyword\">as\u003C/span> e:\n            \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;Error generating API documentation: \u003Cspan class=\"hljs-subst\">{e}\u003C/span>&quot;\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">None\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_changelog\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Generate changelog from git commits&quot;&quot;&quot;\u003C/span>\n        commits = \u003Cspan class=\"hljs-built_in\">list\u003C/span>(self.repo.iter_commits(\u003Cspan class=\"hljs-string\">&#x27;HEAD&#x27;\u003C/span>, max_count=\u003Cspan class=\"hljs-number\">50\u003C/span>))\n        \n        changelog_entries = []\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> commit \u003Cspan class=\"hljs-keyword\">in\u003C/span> commits:\n            \u003Cspan class=\"hljs-comment\"># Parse conventional commit format\u003C/span>\n            message = commit.message.strip()\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;:&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> message:\n                type_scope, description = message.split(\u003Cspan class=\"hljs-string\">&#x27;:&#x27;\u003C/span>, \u003Cspan class=\"hljs-number\">1\u003C/span>)\n                entry = {\n                    \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: type_scope.strip(),\n                    \u003Cspan class=\"hljs-string\">&#x27;description&#x27;\u003C/span>: description.strip(),\n                    \u003Cspan class=\"hljs-string\">&#x27;hash&#x27;\u003C/span>: commit.hexsha[:\u003Cspan class=\"hljs-number\">8\u003C/span>],\n                    \u003Cspan class=\"hljs-string\">&#x27;date&#x27;\u003C/span>: commit.committed_datetime.strftime(\u003Cspan class=\"hljs-string\">&quot;%Y-%m-%d&quot;\u003C/span>),\n                    \u003Cspan class=\"hljs-string\">&#x27;author&#x27;\u003C/span>: commit.author.name\n                }\n                changelog_entries.append(entry)\n        \n\n        template = Template(\u003Cspan class=\"hljs-string\">&quot;&quot;&quot;\n---\ntitle: &quot;Project Changelog&quot;\ndescription: &quot;Recent changes and updates to the project&quot;\ndate: {{ date }}\nauthor: Changelog Generator\ncategory: Reference\nlayout: changelog\n---\n\n# Project Changelog\n\nThis changelog is automatically generated from git commits using conventional commit format.\n\n{% for entry in entries %}\n## {{ entry.date }} - {{ entry.hash }}\n\n**{{ entry.type }}**: {{ entry.description }}  \n*Author: {{ entry.author }}*\n\n{% endfor %}\n&quot;&quot;&quot;\u003C/span>)\n\n        \n        content = template.render(\n            entries=changelog_entries,\n            date=datetime.now().strftime(\u003Cspan class=\"hljs-string\">&quot;%Y-%m-%d&quot;\u003C/span>)\n        )\n        \n        output_path = Path(\u003Cspan class=\"hljs-string\">&quot;pages/changelog.md&quot;\u003C/span>)\n        output_path.write_text(content)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> output_path\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_contributor_guide\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Generate contributor guide from repository data&quot;&quot;&quot;\u003C/span>\n        contributors = []\n        \n        \u003Cspan class=\"hljs-comment\"># Get contributor statistics\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> commit \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.repo.iter_commits():\n            author = commit.author.name\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> author \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> [c[\u003Cspan class=\"hljs-string\">&#x27;name&#x27;\u003C/span>] \u003Cspan class=\"hljs-keyword\">for\u003C/span> c \u003Cspan class=\"hljs-keyword\">in\u003C/span> contributors]:\n                contributors.append({\n                    \u003Cspan class=\"hljs-string\">&#x27;name&#x27;\u003C/span>: author,\n                    \u003Cspan class=\"hljs-string\">&#x27;email&#x27;\u003C/span>: commit.author.email,\n                    \u003Cspan class=\"hljs-string\">&#x27;commits&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">1\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;first_commit&#x27;\u003C/span>: commit.committed_datetime\n                })\n            \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n                \u003Cspan class=\"hljs-keyword\">for\u003C/span> c \u003Cspan class=\"hljs-keyword\">in\u003C/span> contributors:\n                    \u003Cspan class=\"hljs-keyword\">if\u003C/span> c[\u003Cspan class=\"hljs-string\">&#x27;name&#x27;\u003C/span>] == author:\n                        c[\u003Cspan class=\"hljs-string\">&#x27;commits&#x27;\u003C/span>] += \u003Cspan class=\"hljs-number\">1\u003C/span>\n                        \u003Cspan class=\"hljs-keyword\">if\u003C/span> commit.committed_datetime &lt; c[\u003Cspan class=\"hljs-string\">&#x27;first_commit&#x27;\u003C/span>]:\n                            c[\u003Cspan class=\"hljs-string\">&#x27;first_commit&#x27;\u003C/span>] = commit.committed_datetime\n        \n        \u003Cspan class=\"hljs-comment\"># Sort by commit count\u003C/span>\n        contributors.sort(key=\u003Cspan class=\"hljs-keyword\">lambda\u003C/span> x: x[\u003Cspan class=\"hljs-string\">&#x27;commits&#x27;\u003C/span>], reverse=\u003Cspan class=\"hljs-literal\">True\u003C/span>)\n        \n\n        template = Template(\u003Cspan class=\"hljs-string\">&quot;&quot;&quot;\n---\ntitle: &quot;Contributing to {{ project_name }}&quot;\ndescription: &quot;Guidelines for contributing to the project&quot;\ndate: {{ date }}\nauthor: Contribution Guide Generator\ncategory: Guide\nlayout: page\n---\n\n# Contributing to {{ project_name }}\n\nThank you for considering contributing to our project! This guide provides information about how to contribute effectively.\n\n## Our Contributors\n\nWe&#x27;re grateful to all our contributors:\n\n{% for contributor in contributors[:10] %}\n- **{{ contributor.name }}** - {{ contributor.commits }} commits (since {{ contributor.first_commit.strftime(&#x27;%Y-%m-%d&#x27;) }})\n{% endfor %}\n\n## How to Contribute\n\n### 1. Fork the Repository\n\n```bash\ngit clone https://github.com/{{ github_repo }}.git\ncd {{ project_name }}\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch3 id=\"2-create-a-feature-branch\">2. Create a Feature Branch\u003C/h3>\n\u003Cpre>\u003Ccode class=\"hljs language-bash\">git checkout -b feature/your-feature-name\n\u003C/code>\u003C/pre>\u003Ch3 id=\"3-make-your-changes\">3. Make Your Changes\u003C/h3>\n\u003Cul>\n\u003Cli>Follow our coding standards\u003C/li>\n\u003Cli>Add tests for new functionality\u003C/li>\n\u003Cli>Update documentation as needed\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"4-commit-your-changes\">4. Commit Your Changes\u003C/h3>\n\u003Cp>We use conventional commit format:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-bash\">git commit -m \u003Cspan class=\"hljs-string\">&quot;feat: add new feature description&quot;\u003C/span>\ngit commit -m \u003Cspan class=\"hljs-string\">&quot;fix: resolve bug in component&quot;\u003C/span>\ngit commit -m \u003Cspan class=\"hljs-string\">&quot;docs: update API documentation&quot;\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch3 id=\"5-submit-a-pull-request\">5. Submit a Pull Request\u003C/h3>\n\u003Cul>\n\u003Cli>Ensure your branch is up to date with main\u003C/li>\n\u003Cli>Write a clear description of your changes\u003C/li>\n\u003Cli>Reference any related issues\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"development-setup\">Development Setup\u003C/h2>\n\u003Cpre>\u003Ccode class=\"hljs language-bash\">\u003Cspan class=\"hljs-comment\"># Install dependencies\u003C/span>\nnpm install\nbundle install\n\n\u003Cspan class=\"hljs-comment\"># Run development server\u003C/span>\n./exe/dev\n\n\u003Cspan class=\"hljs-comment\"># Run tests\u003C/span>\nnpm \u003Cspan class=\"hljs-built_in\">test\u003C/span>\nbundle \u003Cspan class=\"hljs-built_in\">exec\u003C/span> rspec\n\u003C/code>\u003C/pre>\u003Ch2 id=\"code-style-guidelines\">Code Style Guidelines\u003C/h2>\n\u003Cul>\n\u003Cli>Use consistent indentation (2 spaces)\u003C/li>\n\u003Cli>Follow existing naming conventions\u003C/li>\n\u003Cli>Add comments for complex logic\u003C/li>\n\u003Cli>Ensure code passes all linting checks\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"documentation-standards\">Documentation Standards\u003C/h2>\n\u003Cul>\n\u003Cli>Update relevant documentation with code changes\u003C/li>\n\u003Cli>Use clear, concise language\u003C/li>\n\u003Cli>Include code examples where appropriate\u003C/li>\n\u003Cli>Test documentation examples\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"need-help\">Need Help?\u003C/h2>\n\u003Cul>\n\u003Cli>Check existing issues and discussions\u003C/li>\n\u003Cli>Join our community chat\u003C/li>\n\u003Cli>Read the project documentation\u003C/li>\n\u003Cli>Contact the maintainers\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cp>\u003Cem>This guide was automatically generated on {{ date }}\u003C/em>\u003Cbr>&quot;&quot;&quot;)\u003C/p>\n\u003Cpre>\u003Ccode>    content = template.render(\n        contributors=contributors,\n        project_name=self.repo.working_dir.split(&#39;/&#39;)[-1],\n        github_repo=&quot;your-org/your-repo&quot;,  # Configure this\n        date=datetime.now().strftime(&quot;%Y-%m-%d&quot;)\n    )\n    \n    output_path = Path(&quot;pages/contributing.md&quot;)\n    output_path.write_text(content)\n    \n    return output_path\n\u003C/code>\u003C/pre>\u003Cp>def main():\u003Cbr>    &quot;&quot;&quot;Main content generation function&quot;&quot;&quot;\u003Cbr>    generator = DynamicContentGenerator()\u003C/p>\n\u003Cpre>\u003Ccode># Generate different types of content\ngenerated_files = []\n\n# API documentation (if configured)\nif &#39;openapi_spec&#39; in generator.config:\n    api_doc = generator.generate_api_documentation(generator.config[&#39;openapi_spec&#39;])\n    if api_doc:\n        generated_files.append(api_doc)\n\n# Changelog\nchangelog = generator.generate_changelog()\ngenerated_files.append(changelog)\n\n# Contributor guide\ncontrib_guide = generator.generate_contributor_guide()\ngenerated_files.append(contrib_guide)\n\nprint(f&quot;Generated {len(generated_files)} content files:&quot;)\nfor file in generated_files:\n    print(f&quot;  - {file}&quot;)\n\u003C/code>\u003C/pre>\u003Cp>if \u003Cstrong>name\u003C/strong> == &quot;\u003Cstrong>main\u003C/strong>&quot;:\u003Cbr>    main()\u003C/p>\n\u003Cpre>\u003Ccode>\n### Multi-Platform Publishing Automation\n\nSimultaneous publishing to multiple platforms:\n\n```javascript\n// scripts/multi-platform-publisher.js - Multi-platform content publishing\nconst fs = require(&#39;fs&#39;).promises;\nconst path = require(&#39;path&#39;);\nconst matter = require(&#39;gray-matter&#39;);\nconst MarkdownIt = require(&#39;markdown-it&#39;);\nconst axios = require(&#39;axios&#39;);\n\nclass MultiPlatformPublisher {\n    constructor(config = {}) {\n        this.config = {\n            platforms: [&#39;dev.to&#39;, &#39;medium&#39;, &#39;hashnode&#39;, &#39;ghost&#39;],\n            outputFormats: [&#39;html&#39;, &#39;markdown&#39;, &#39;json&#39;],\n            ...config\n        };\n        \n        this.md = new MarkdownIt({\n            html: true,\n            breaks: true,\n            linkify: true\n        });\n        \n        this.publishResults = [];\n    }\n    \n    async publishContent(contentPath, platforms = null) {\n        try {\n            console.log(`Publishing content from: ${contentPath}`);\n            \n            // Load and parse content\n            const content = await this.loadContent(contentPath);\n            \n            // Determine platforms to publish to\n            const targetPlatforms = platforms || this.config.platforms;\n            \n            // Publish to each platform\n            const publishPromises = targetPlatforms.map(platform =&gt; \n                this.publishToPlatform(content, platform)\n            );\n            \n            const results = await Promise.allSettled(publishPromises);\n            \n            this.publishResults = results.map((result, index) =&gt; ({\n                platform: targetPlatforms[index],\n                status: result.status,\n                value: result.value,\n                reason: result.reason?.message\n            }));\n            \n            return this.publishResults;\n            \n        } catch (error) {\n            console.error(&#39;Publishing failed:&#39;, error);\n            throw error;\n        }\n    }\n    \n    async loadContent(contentPath) {\n        const fileContent = await fs.readFile(contentPath, &#39;utf8&#39;);\n        const { data: frontmatter, content: body } = matter(fileContent);\n        \n        return {\n            frontmatter,\n            markdown: body,\n            html: this.md.render(body),\n            filePath: contentPath,\n            fileName: path.basename(contentPath)\n        };\n    }\n    \n    async publishToPlatform(content, platform) {\n        console.log(`Publishing to ${platform}...`);\n        \n        switch (platform) {\n            case &#39;dev.to&#39;:\n                return await this.publishToDevTo(content);\n            case &#39;medium&#39;:\n                return await this.publishToMedium(content);\n            case &#39;hashnode&#39;:\n                return await this.publishToHashnode(content);\n            case &#39;ghost&#39;:\n                return await this.publishToGhost(content);\n            case &#39;wordpress&#39;:\n                return await this.publishToWordPress(content);\n            default:\n                throw new Error(`Unsupported platform: ${platform}`);\n        }\n    }\n    \n    async publishToDevTo(content) {\n        const devToApiKey = process.env.DEV_TO_API_KEY;\n        if (!devToApiKey) {\n            throw new Error(&#39;DEV_TO_API_KEY not configured&#39;);\n        }\n        \n        const article = {\n            article: {\n                title: content.frontmatter.title,\n                body_markdown: content.markdown,\n                published: false, // Start as draft\n                description: content.frontmatter.description,\n                tags: this.extractTags(content.frontmatter.keywords, 4),\n                canonical_url: content.frontmatter.canonical_url,\n                main_image: content.frontmatter.image?.url\n            }\n        };\n        \n        try {\n            const response = await axios.post(&#39;https://dev.to/api/articles&#39;, article, {\n                headers: {\n                    &#39;api-key&#39;: devToApiKey,\n                    &#39;Content-Type&#39;: &#39;application/json&#39;\n                }\n            });\n            \n            return {\n                success: true,\n                platform: &#39;dev.to&#39;,\n                url: response.data.url,\n                id: response.data.id\n            };\n            \n        } catch (error) {\n            throw new Error(`Dev.to publishing failed: ${error.response?.data?.error || error.message}`);\n        }\n    }\n    \n    async publishToMedium(content) {\n        const mediumToken = process.env.MEDIUM_TOKEN;\n        if (!mediumToken) {\n            throw new Error(&#39;MEDIUM_TOKEN not configured&#39;);\n        }\n        \n        // Get user ID first\n        const userResponse = await axios.get(&#39;https://api.medium.com/v1/me&#39;, {\n            headers: {\n                &#39;Authorization&#39;: `Bearer ${mediumToken}`\n            }\n        });\n        \n        const userId = userResponse.data.data.id;\n        \n        const article = {\n            title: content.frontmatter.title,\n            contentFormat: &#39;html&#39;,\n            content: content.html,\n            publishStatus: &#39;draft&#39;,\n            tags: this.extractTags(content.frontmatter.keywords, 5),\n            canonicalUrl: content.frontmatter.canonical_url\n        };\n        \n        try {\n            const response = await axios.post(\n                `https://api.medium.com/v1/users/${userId}/posts`,\n                article,\n                {\n                    headers: {\n                        &#39;Authorization&#39;: `Bearer ${mediumToken}`,\n                        &#39;Content-Type&#39;: &#39;application/json&#39;\n                    }\n                }\n            );\n            \n            return {\n                success: true,\n                platform: &#39;medium&#39;,\n                url: response.data.data.url,\n                id: response.data.data.id\n            };\n            \n        } catch (error) {\n            throw new Error(`Medium publishing failed: ${error.response?.data?.errors?.[0]?.message || error.message}`);\n        }\n    }\n    \n    async publishToHashnode(content) {\n        const hashnodeApiKey = process.env.HASHNODE_API_KEY;\n        const publicationId = process.env.HASHNODE_PUBLICATION_ID;\n        \n        if (!hashnodeApiKey || !publicationId) {\n            throw new Error(&#39;HASHNODE_API_KEY or HASHNODE_PUBLICATION_ID not configured&#39;);\n        }\n        \n        const mutation = `\n            mutation CreatePost($input: CreatePostInput!) {\n                createPost(input: $input) {\n                    success\n                    post {\n                        id\n                        url\n                        title\n                    }\n                }\n            }\n        `;\n        \n        const variables = {\n            input: {\n                title: content.frontmatter.title,\n                contentMarkdown: content.markdown,\n                publicationId: publicationId,\n                tags: this.extractTags(content.frontmatter.keywords, 10).map(tag =&gt; ({ name: tag })),\n                isDraft: true\n            }\n        };\n        \n        try {\n            const response = await axios.post(&#39;https://api.hashnode.com&#39;, {\n                query: mutation,\n                variables\n            }, {\n                headers: {\n                    &#39;Authorization&#39;: hashnodeApiKey,\n                    &#39;Content-Type&#39;: &#39;application/json&#39;\n                }\n            });\n            \n            if (response.data.errors) {\n                throw new Error(response.data.errors[0].message);\n            }\n            \n            return {\n                success: true,\n                platform: &#39;hashnode&#39;,\n                url: response.data.data.createPost.post.url,\n                id: response.data.data.createPost.post.id\n            };\n            \n        } catch (error) {\n            throw new Error(`Hashnode publishing failed: ${error.message}`);\n        }\n    }\n    \n    async publishToGhost(content) {\n        const ghostApiKey = process.env.GHOST_API_KEY;\n        const ghostApiUrl = process.env.GHOST_API_URL;\n        \n        if (!ghostApiKey || !ghostApiUrl) {\n            throw new Error(&#39;Ghost API credentials not configured&#39;);\n        }\n        \n        const jwt = require(&#39;jsonwebtoken&#39;);\n        const [id, secret] = ghostApiKey.split(&#39;:&#39;);\n        \n        const token = jwt.sign({}, Buffer.from(secret, &#39;hex&#39;), {\n            keyid: id,\n            algorithm: &#39;HS256&#39;,\n            expiresIn: &#39;5m&#39;,\n            audience: &#39;/v3/admin/&#39;\n        });\n        \n        const post = {\n            posts: [{\n                title: content.frontmatter.title,\n                html: content.html,\n                status: &#39;draft&#39;,\n                excerpt: content.frontmatter.description,\n                tags: this.extractTags(content.frontmatter.keywords, 10),\n                created_at: new Date().toISOString()\n            }]\n        };\n        \n        try {\n            const response = await axios.post(`${ghostApiUrl}/ghost/api/v3/admin/posts/`, post, {\n                headers: {\n                    &#39;Authorization&#39;: `Ghost ${token}`,\n                    &#39;Content-Type&#39;: &#39;application/json&#39;\n                }\n            });\n            \n            return {\n                success: true,\n                platform: &#39;ghost&#39;,\n                url: response.data.posts[0].url,\n                id: response.data.posts[0].id\n            };\n            \n        } catch (error) {\n            throw new Error(`Ghost publishing failed: ${error.response?.data?.errors?.[0]?.message || error.message}`);\n        }\n    }\n    \n    extractTags(keywords, maxTags = 5) {\n        if (!keywords) return [];\n        \n        if (typeof keywords === &#39;string&#39;) {\n            return keywords\n                .split(&#39;,&#39;)\n                .map(tag =&gt; tag.trim().toLowerCase())\n                .filter(tag =&gt; tag.length &gt; 0)\n                .slice(0, maxTags);\n        }\n        \n        return keywords.slice(0, maxTags);\n    }\n    \n    async generatePublishReport() {\n        const report = {\n            timestamp: new Date().toISOString(),\n            summary: {\n                total: this.publishResults.length,\n                successful: this.publishResults.filter(r =&gt; r.status === &#39;fulfilled&#39;).length,\n                failed: this.publishResults.filter(r =&gt; r.status === &#39;rejected&#39;).length\n            },\n            results: this.publishResults\n        };\n        \n        // Write JSON report\n        await fs.writeFile(&#39;publish-report.json&#39;, JSON.stringify(report, null, 2));\n        \n        // Generate markdown report\n        const markdownReport = this.generateMarkdownReport(report);\n        await fs.writeFile(&#39;publish-report.md&#39;, markdownReport);\n        \n        return report;\n    }\n    \n    generateMarkdownReport(report) {\n        let markdown = `# Publishing Report\\n\\n`;\n        markdown += `**Generated:** ${report.timestamp}\\n\\n`;\n        markdown += `## Summary\\n\\n`;\n        markdown += `- **Total Platforms:** ${report.summary.total}\\n`;\n        markdown += `- **Successful:** ${report.summary.successful}\\n`;\n        markdown += `- **Failed:** ${report.summary.failed}\\n\\n`;\n        \n        if (report.summary.successful &gt; 0) {\n            markdown += `## ✅ Successful Publications\\n\\n`;\n            report.results\n                .filter(r =&gt; r.status === &#39;fulfilled&#39;)\n                .forEach(result =&gt; {\n                    markdown += `### ${result.platform}\\n`;\n                    markdown += `- **Status:** Published\\n`;\n                    if (result.value?.url) {\n                        markdown += `- **URL:** ${result.value.url}\\n`;\n                    }\n                    markdown += `\\n`;\n                });\n        }\n        \n        if (report.summary.failed &gt; 0) {\n            markdown += `## ❌ Failed Publications\\n\\n`;\n            report.results\n                .filter(r =&gt; r.status === &#39;rejected&#39;)\n                .forEach(result =&gt; {\n                    markdown += `### ${result.platform}\\n`;\n                    markdown += `- **Error:** ${result.reason}\\n\\n`;\n                });\n        }\n        \n        return markdown;\n    }\n}\n\n// CLI usage\nasync function main() {\n    const args = process.argv.slice(2);\n    const contentPath = args[0];\n    const platforms = args[1] ? args[1].split(&#39;,&#39;) : null;\n    \n    if (!contentPath) {\n        console.error(&#39;Usage: node multi-platform-publisher.js &lt;content-path&gt; [platforms]&#39;);\n        process.exit(1);\n    }\n    \n    const publisher = new MultiPlatformPublisher();\n    \n    try {\n        console.log(&#39;Starting multi-platform publishing...&#39;);\n        const results = await publisher.publishContent(contentPath, platforms);\n        \n        console.log(&#39;\\nPublishing Results:&#39;);\n        results.forEach(result =&gt; {\n            const status = result.status === &#39;fulfilled&#39; ? &#39;✅&#39; : &#39;❌&#39;;\n            console.log(`${status} ${result.platform}: ${result.value?.url || result.reason}`);\n        });\n        \n        await publisher.generatePublishReport();\n        console.log(&#39;\\nPublish report generated: publish-report.md&#39;);\n        \n    } catch (error) {\n        console.error(&#39;Publishing failed:&#39;, error.message);\n        process.exit(1);\n    }\n}\n\nif (require.main === module) {\n    main();\n}\n\nmodule.exports = MultiPlatformPublisher;\n\u003C/code>\u003C/pre>\u003Ch2 id=\"integration-with-modern-development-workflows\">Integration with Modern Development Workflows\u003C/h2>\n\u003Cp>Markdown automation workflows integrate seamlessly with comprehensive development practices. When combined with \u003Ca href=\"/blog/markdown-custom-css-classes-styling-complete-guide\">custom CSS styling and visual design systems\u003C/a>, automated workflows can ensure consistent branding and presentation across all published content while maintaining quality standards through automated validation and testing processes.\u003C/p>\n\u003Cp>For comprehensive content management systems, automation complements \u003Ca href=\"/blog/markdown-navigation-menus-site-structure-complete-guide\">navigation structure and site organization\u003C/a> by automatically generating and updating documentation hierarchies, cross-references, and content relationships based on file structure changes and metadata updates, ensuring documentation remains organized and discoverable.\u003C/p>\n\u003Cp>When building sophisticated publication platforms, automation workflows work effectively with \u003Ca href=\"/blog/react-markdown-rendering-guide\">React component integration and dynamic rendering\u003C/a> to create end-to-end content pipelines that transform static Markdown files into interactive web applications with automated testing, optimization, and deployment capabilities.\u003C/p>\n\u003Ch2 id=\"monitoring-and-analytics-integration\">Monitoring and Analytics Integration\u003C/h2>\n\u003Ch3 id=\"automated-performance-monitoring\">Automated Performance Monitoring\u003C/h3>\n\u003Cp>Track content performance and user engagement automatically:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-python\">\u003Cspan class=\"hljs-comment\"># scripts/content-analytics.py - Automated content performance monitoring\u003C/span>\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> os\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> json\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> requests\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> datetime \u003Cspan class=\"hljs-keyword\">import\u003C/span> datetime, timedelta\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> pathlib \u003Cspan class=\"hljs-keyword\">import\u003C/span> Path\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> pandas \u003Cspan class=\"hljs-keyword\">as\u003C/span> pd\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> google.analytics.data_v1beta \u003Cspan class=\"hljs-keyword\">import\u003C/span> BetaAnalyticsDataClient\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> google.analytics.data_v1beta.types \u003Cspan class=\"hljs-keyword\">import\u003C/span> DateRange, Dimension, Metric, RunReportRequest\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">ContentAnalyticsMonitor\u003C/span>:\n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">__init__\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>):\n        self.ga_client = BetaAnalyticsDataClient()\n        self.property_id = os.getenv(\u003Cspan class=\"hljs-string\">&#x27;GA_PROPERTY_ID&#x27;\u003C/span>)\n        self.github_token = os.getenv(\u003Cspan class=\"hljs-string\">&#x27;GITHUB_TOKEN&#x27;\u003C/span>)\n        self.repo_name = os.getenv(\u003Cspan class=\"hljs-string\">&#x27;GITHUB_REPOSITORY&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;markdowntools/blog&#x27;\u003C/span>)\n        \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">get_content_performance\u003C/span>(\u003Cspan class=\"hljs-params\">self, days=\u003Cspan class=\"hljs-number\">30\u003C/span>\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Get content performance data from Google Analytics&quot;&quot;&quot;\u003C/span>\n        request = RunReportRequest(\n            \u003Cspan class=\"hljs-built_in\">property\u003C/span>=\u003Cspan class=\"hljs-string\">f&quot;properties/\u003Cspan class=\"hljs-subst\">{self.property_id}\u003C/span>&quot;\u003C/span>,\n            dimensions=[\n                Dimension(name=\u003Cspan class=\"hljs-string\">&quot;pagePath&quot;\u003C/span>),\n                Dimension(name=\u003Cspan class=\"hljs-string\">&quot;pageTitle&quot;\u003C/span>)\n            ],\n            metrics=[\n                Metric(name=\u003Cspan class=\"hljs-string\">&quot;screenPageViews&quot;\u003C/span>),\n                Metric(name=\u003Cspan class=\"hljs-string\">&quot;averageSessionDuration&quot;\u003C/span>),\n                Metric(name=\u003Cspan class=\"hljs-string\">&quot;bounceRate&quot;\u003C/span>),\n                Metric(name=\u003Cspan class=\"hljs-string\">&quot;engagementRate&quot;\u003C/span>)\n            ],\n            date_ranges=[DateRange(\n                start_date=\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{days}\u003C/span>daysAgo&quot;\u003C/span>,\n                end_date=\u003Cspan class=\"hljs-string\">&quot;today&quot;\u003C/span>\n            )],\n            dimension_filter=self.create_page_filter()\n        )\n        \n        response = self.ga_client.run_report(request)\n        \n        analytics_data = []\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> row \u003Cspan class=\"hljs-keyword\">in\u003C/span> response.rows:\n            analytics_data.append({\n                \u003Cspan class=\"hljs-string\">&#x27;path&#x27;\u003C/span>: row.dimension_values[\u003Cspan class=\"hljs-number\">0\u003C/span>].value,\n                \u003Cspan class=\"hljs-string\">&#x27;title&#x27;\u003C/span>: row.dimension_values[\u003Cspan class=\"hljs-number\">1\u003C/span>].value,\n                \u003Cspan class=\"hljs-string\">&#x27;pageviews&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">int\u003C/span>(row.metric_values[\u003Cspan class=\"hljs-number\">0\u003C/span>].value),\n                \u003Cspan class=\"hljs-string\">&#x27;avg_duration&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">float\u003C/span>(row.metric_values[\u003Cspan class=\"hljs-number\">1\u003C/span>].value),\n                \u003Cspan class=\"hljs-string\">&#x27;bounce_rate&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">float\u003C/span>(row.metric_values[\u003Cspan class=\"hljs-number\">2\u003C/span>].value),\n                \u003Cspan class=\"hljs-string\">&#x27;engagement_rate&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">float\u003C/span>(row.metric_values[\u003Cspan class=\"hljs-number\">3\u003C/span>].value)\n            })\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-built_in\">sorted\u003C/span>(analytics_data, key=\u003Cspan class=\"hljs-keyword\">lambda\u003C/span> x: x[\u003Cspan class=\"hljs-string\">&#x27;pageviews&#x27;\u003C/span>], reverse=\u003Cspan class=\"hljs-literal\">True\u003C/span>)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">create_page_filter\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Create filter for blog/docs pages&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">from\u003C/span> google.analytics.data_v1beta.types \u003Cspan class=\"hljs-keyword\">import\u003C/span> Filter, FilterExpression\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> FilterExpression(\n            \u003Cspan class=\"hljs-built_in\">filter\u003C/span>=Filter(\n                field_name=\u003Cspan class=\"hljs-string\">&quot;pagePath&quot;\u003C/span>,\n                string_filter=Filter.StringFilter(\n                    match_type=Filter.StringFilter.MatchType.CONTAINS,\n                    value=\u003Cspan class=\"hljs-string\">&quot;/posts/&quot;\u003C/span>\n                )\n            )\n        )\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">get_github_metrics\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Get GitHub repository metrics&quot;&quot;&quot;\u003C/span>\n        headers = {\u003Cspan class=\"hljs-string\">&#x27;Authorization&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">f&#x27;token \u003Cspan class=\"hljs-subst\">{self.github_token}\u003C/span>&#x27;\u003C/span>}\n        \n        \u003Cspan class=\"hljs-comment\"># Repository stats\u003C/span>\n        repo_url = \u003Cspan class=\"hljs-string\">f&quot;https://api.github.com/repos/\u003Cspan class=\"hljs-subst\">{self.repo_name}\u003C/span>&quot;\u003C/span>\n        repo_response = requests.get(repo_url, headers=headers)\n        repo_data = repo_response.json()\n        \n        \u003Cspan class=\"hljs-comment\"># Recent commits\u003C/span>\n        commits_url = \u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{repo_url}\u003C/span>/commits&quot;\u003C/span>\n        commits_response = requests.get(commits_url, headers=headers)\n        commits_data = commits_response.json()\n        \n        \u003Cspan class=\"hljs-comment\"># Issues and PRs\u003C/span>\n        issues_url = \u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{repo_url}\u003C/span>/issues?state=all&amp;since=\u003Cspan class=\"hljs-subst\">{(datetime.now() - timedelta(days=\u003Cspan class=\"hljs-number\">30\u003C/span>)).isoformat()}\u003C/span>&quot;\u003C/span>\n        issues_response = requests.get(issues_url, headers=headers)\n        issues_data = issues_response.json()\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> {\n            \u003Cspan class=\"hljs-string\">&#x27;stars&#x27;\u003C/span>: repo_data.get(\u003Cspan class=\"hljs-string\">&#x27;stargazers_count&#x27;\u003C/span>, \u003Cspan class=\"hljs-number\">0\u003C/span>),\n            \u003Cspan class=\"hljs-string\">&#x27;forks&#x27;\u003C/span>: repo_data.get(\u003Cspan class=\"hljs-string\">&#x27;forks_count&#x27;\u003C/span>, \u003Cspan class=\"hljs-number\">0\u003C/span>),\n            \u003Cspan class=\"hljs-string\">&#x27;watchers&#x27;\u003C/span>: repo_data.get(\u003Cspan class=\"hljs-string\">&#x27;watchers_count&#x27;\u003C/span>, \u003Cspan class=\"hljs-number\">0\u003C/span>),\n            \u003Cspan class=\"hljs-string\">&#x27;open_issues&#x27;\u003C/span>: repo_data.get(\u003Cspan class=\"hljs-string\">&#x27;open_issues_count&#x27;\u003C/span>, \u003Cspan class=\"hljs-number\">0\u003C/span>),\n            \u003Cspan class=\"hljs-string\">&#x27;recent_commits&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">len\u003C/span>(commits_data),\n            \u003Cspan class=\"hljs-string\">&#x27;recent_issues&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">len\u003C/span>([i \u003Cspan class=\"hljs-keyword\">for\u003C/span> i \u003Cspan class=\"hljs-keyword\">in\u003C/span> issues_data \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;pull_request&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> i]),\n            \u003Cspan class=\"hljs-string\">&#x27;recent_prs&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">len\u003C/span>([i \u003Cspan class=\"hljs-keyword\">for\u003C/span> i \u003Cspan class=\"hljs-keyword\">in\u003C/span> issues_data \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;pull_request&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> i])\n        }\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_performance_report\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Generate comprehensive performance report&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">&quot;Generating content performance report...&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-comment\"># Get analytics data\u003C/span>\n        analytics_data = self.get_content_performance()\n        github_metrics = self.get_github_metrics()\n        \n        \u003Cspan class=\"hljs-comment\"># Analyze top performing content\u003C/span>\n        top_content = analytics_data[:\u003Cspan class=\"hljs-number\">10\u003C/span>]\n        low_performing = [item \u003Cspan class=\"hljs-keyword\">for\u003C/span> item \u003Cspan class=\"hljs-keyword\">in\u003C/span> analytics_data \u003Cspan class=\"hljs-keyword\">if\u003C/span> item[\u003Cspan class=\"hljs-string\">&#x27;pageviews&#x27;\u003C/span>] &lt; \u003Cspan class=\"hljs-number\">100\u003C/span>]\n        \n        report = {\n            \u003Cspan class=\"hljs-string\">&#x27;generated_at&#x27;\u003C/span>: datetime.now().isoformat(),\n            \u003Cspan class=\"hljs-string\">&#x27;period&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;30 days&#x27;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&#x27;summary&#x27;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&#x27;total_posts_analyzed&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">len\u003C/span>(analytics_data),\n                \u003Cspan class=\"hljs-string\">&#x27;total_pageviews&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">sum\u003C/span>(item[\u003Cspan class=\"hljs-string\">&#x27;pageviews&#x27;\u003C/span>] \u003Cspan class=\"hljs-keyword\">for\u003C/span> item \u003Cspan class=\"hljs-keyword\">in\u003C/span> analytics_data),\n                \u003Cspan class=\"hljs-string\">&#x27;avg_pageviews_per_post&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">sum\u003C/span>(item[\u003Cspan class=\"hljs-string\">&#x27;pageviews&#x27;\u003C/span>] \u003Cspan class=\"hljs-keyword\">for\u003C/span> item \u003Cspan class=\"hljs-keyword\">in\u003C/span> analytics_data) / \u003Cspan class=\"hljs-built_in\">len\u003C/span>(analytics_data) \u003Cspan class=\"hljs-keyword\">if\u003C/span> analytics_data \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-number\">0\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;top_performing_count&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">len\u003C/span>(top_content),\n                \u003Cspan class=\"hljs-string\">&#x27;underperforming_count&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">len\u003C/span>(low_performing)\n            },\n            \u003Cspan class=\"hljs-string\">&#x27;top_performing_content&#x27;\u003C/span>: top_content,\n            \u003Cspan class=\"hljs-string\">&#x27;underperforming_content&#x27;\u003C/span>: low_performing[:\u003Cspan class=\"hljs-number\">10\u003C/span>],\n            \u003Cspan class=\"hljs-string\">&#x27;github_metrics&#x27;\u003C/span>: github_metrics,\n            \u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>: self.generate_recommendations(analytics_data)\n        }\n        \n        \u003Cspan class=\"hljs-comment\"># Save report\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;content-performance-report.json&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;w&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n            json.dump(report, f, indent=\u003Cspan class=\"hljs-number\">2\u003C/span>)\n        \n        \u003Cspan class=\"hljs-comment\"># Generate markdown report\u003C/span>\n        markdown_report = self.generate_markdown_report(report)\n        \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;content-performance-report.md&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;w&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n            f.write(markdown_report)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> report\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_recommendations\u003C/span>(\u003Cspan class=\"hljs-params\">self, analytics_data\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Generate content improvement recommendations&quot;&quot;&quot;\u003C/span>\n        recommendations = []\n        \n        \u003Cspan class=\"hljs-comment\"># High bounce rate content\u003C/span>\n        high_bounce = [item \u003Cspan class=\"hljs-keyword\">for\u003C/span> item \u003Cspan class=\"hljs-keyword\">in\u003C/span> analytics_data \u003Cspan class=\"hljs-keyword\">if\u003C/span> item[\u003Cspan class=\"hljs-string\">&#x27;bounce_rate&#x27;\u003C/span>] &gt; \u003Cspan class=\"hljs-number\">0.8\u003C/span>]\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> high_bounce:\n            recommendations.append({\n                \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;high_bounce_rate&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;severity&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;medium&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;title&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;High Bounce Rate Content&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;description&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">len\u003C/span>(high_bounce)}\u003C/span> posts have bounce rates above 80%&quot;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;action&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Review content structure, add internal links, improve readability&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;affected_posts&#x27;\u003C/span>: [item[\u003Cspan class=\"hljs-string\">&#x27;title&#x27;\u003C/span>] \u003Cspan class=\"hljs-keyword\">for\u003C/span> item \u003Cspan class=\"hljs-keyword\">in\u003C/span> high_bounce[:\u003Cspan class=\"hljs-number\">5\u003C/span>]]\n            })\n        \n        \u003Cspan class=\"hljs-comment\"># Low engagement content\u003C/span>\n        low_engagement = [item \u003Cspan class=\"hljs-keyword\">for\u003C/span> item \u003Cspan class=\"hljs-keyword\">in\u003C/span> analytics_data \u003Cspan class=\"hljs-keyword\">if\u003C/span> item[\u003Cspan class=\"hljs-string\">&#x27;engagement_rate&#x27;\u003C/span>] &lt; \u003Cspan class=\"hljs-number\">0.3\u003C/span>]\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> low_engagement:\n            recommendations.append({\n                \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;low_engagement&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;severity&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;high&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;title&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Low Engagement Content&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;description&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">len\u003C/span>(low_engagement)}\u003C/span> posts have engagement rates below 30%&quot;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;action&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Consider content updates, better CTAs, or content consolidation&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;affected_posts&#x27;\u003C/span>: [item[\u003Cspan class=\"hljs-string\">&#x27;title&#x27;\u003C/span>] \u003Cspan class=\"hljs-keyword\">for\u003C/span> item \u003Cspan class=\"hljs-keyword\">in\u003C/span> low_engagement[:\u003Cspan class=\"hljs-number\">5\u003C/span>]]\n            })\n        \n        \u003Cspan class=\"hljs-comment\"># Short session duration\u003C/span>\n        short_sessions = [item \u003Cspan class=\"hljs-keyword\">for\u003C/span> item \u003Cspan class=\"hljs-keyword\">in\u003C/span> analytics_data \u003Cspan class=\"hljs-keyword\">if\u003C/span> item[\u003Cspan class=\"hljs-string\">&#x27;avg_duration&#x27;\u003C/span>] &lt; \u003Cspan class=\"hljs-number\">60\u003C/span>]\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> short_sessions:\n            recommendations.append({\n                \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;short_sessions&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;severity&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;medium&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;title&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Short Session Duration&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;description&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">len\u003C/span>(short_sessions)}\u003C/span> posts have average session duration under 1 minute&quot;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;action&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Improve content depth, add interactive elements, better formatting&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;affected_posts&#x27;\u003C/span>: [item[\u003Cspan class=\"hljs-string\">&#x27;title&#x27;\u003C/span>] \u003Cspan class=\"hljs-keyword\">for\u003C/span> item \u003Cspan class=\"hljs-keyword\">in\u003C/span> short_sessions[:\u003Cspan class=\"hljs-number\">5\u003C/span>]]\n            })\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> recommendations\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_markdown_report\u003C/span>(\u003Cspan class=\"hljs-params\">self, report\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Generate markdown performance report&quot;&quot;&quot;\u003C/span>\n        markdown = \u003Cspan class=\"hljs-string\">f&quot;&quot;&quot;# Content Performance Report\n\n**Generated:** \u003Cspan class=\"hljs-subst\">{report[\u003Cspan class=\"hljs-string\">&#x27;generated_at&#x27;\u003C/span>]}\u003C/span>  \n**Period:** \u003Cspan class=\"hljs-subst\">{report[\u003Cspan class=\"hljs-string\">&#x27;period&#x27;\u003C/span>]}\u003C/span>\n\n## Summary\n\n- **Total Posts Analyzed:** \u003Cspan class=\"hljs-subst\">{report[\u003Cspan class=\"hljs-string\">&#x27;summary&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;total_posts_analyzed&#x27;\u003C/span>]:,}\u003C/span>\n- **Total Pageviews:** \u003Cspan class=\"hljs-subst\">{report[\u003Cspan class=\"hljs-string\">&#x27;summary&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;total_pageviews&#x27;\u003C/span>]:,}\u003C/span>\n- **Average Pageviews per Post:** \u003Cspan class=\"hljs-subst\">{report[\u003Cspan class=\"hljs-string\">&#x27;summary&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;avg_pageviews_per_post&#x27;\u003C/span>]:\u003Cspan class=\"hljs-number\">.1\u003C/span>f}\u003C/span>\n- **Top Performers:** \u003Cspan class=\"hljs-subst\">{report[\u003Cspan class=\"hljs-string\">&#x27;summary&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;top_performing_count&#x27;\u003C/span>]}\u003C/span>\n- **Underperforming:** \u003Cspan class=\"hljs-subst\">{report[\u003Cspan class=\"hljs-string\">&#x27;summary&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;underperforming_count&#x27;\u003C/span>]}\u003C/span>\n\n## GitHub Metrics\n\n- **⭐ Stars:** \u003Cspan class=\"hljs-subst\">{report[\u003Cspan class=\"hljs-string\">&#x27;github_metrics&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;stars&#x27;\u003C/span>]:,}\u003C/span>\n- **🍴 Forks:** \u003Cspan class=\"hljs-subst\">{report[\u003Cspan class=\"hljs-string\">&#x27;github_metrics&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;forks&#x27;\u003C/span>]:,}\u003C/span>\n- **👀 Watchers:** \u003Cspan class=\"hljs-subst\">{report[\u003Cspan class=\"hljs-string\">&#x27;github_metrics&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;watchers&#x27;\u003C/span>]:,}\u003C/span>\n- **📝 Recent Commits:** \u003Cspan class=\"hljs-subst\">{report[\u003Cspan class=\"hljs-string\">&#x27;github_metrics&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;recent_commits&#x27;\u003C/span>]}\u003C/span>\n- **🐛 Open Issues:** \u003Cspan class=\"hljs-subst\">{report[\u003Cspan class=\"hljs-string\">&#x27;github_metrics&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;open_issues&#x27;\u003C/span>]}\u003C/span>\n\n## 🏆 Top Performing Content\n\n| Title | Pageviews | Engagement Rate | Bounce Rate |\n|-------|-----------|-----------------|-------------|\n&quot;&quot;&quot;\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> item \u003Cspan class=\"hljs-keyword\">in\u003C/span> report[\u003Cspan class=\"hljs-string\">&#x27;top_performing_content&#x27;\u003C/span>]:\n            markdown += \u003Cspan class=\"hljs-string\">f&quot;| \u003Cspan class=\"hljs-subst\">{item[\u003Cspan class=\"hljs-string\">&#x27;title&#x27;\u003C/span>]}\u003C/span> | \u003Cspan class=\"hljs-subst\">{item[\u003Cspan class=\"hljs-string\">&#x27;pageviews&#x27;\u003C/span>]:,}\u003C/span> | \u003Cspan class=\"hljs-subst\">{item[\u003Cspan class=\"hljs-string\">&#x27;engagement_rate&#x27;\u003C/span>]:\u003Cspan class=\"hljs-number\">.1\u003C/span>%}\u003C/span> | \u003Cspan class=\"hljs-subst\">{item[\u003Cspan class=\"hljs-string\">&#x27;bounce_rate&#x27;\u003C/span>]:\u003Cspan class=\"hljs-number\">.1\u003C/span>%}\u003C/span> |\\n&quot;\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> report[\u003Cspan class=\"hljs-string\">&#x27;underperforming_content&#x27;\u003C/span>]:\n            markdown += \u003Cspan class=\"hljs-string\">f&quot;&quot;&quot;\n## ⚠️ Underperforming Content\n\n| Title | Pageviews | Engagement Rate | Bounce Rate |\n|-------|-----------|-----------------|-------------|\n&quot;&quot;&quot;\u003C/span>\n            \n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> item \u003Cspan class=\"hljs-keyword\">in\u003C/span> report[\u003Cspan class=\"hljs-string\">&#x27;underperforming_content&#x27;\u003C/span>]:\n                markdown += \u003Cspan class=\"hljs-string\">f&quot;| \u003Cspan class=\"hljs-subst\">{item[\u003Cspan class=\"hljs-string\">&#x27;title&#x27;\u003C/span>]}\u003C/span> | \u003Cspan class=\"hljs-subst\">{item[\u003Cspan class=\"hljs-string\">&#x27;pageviews&#x27;\u003C/span>]:,}\u003C/span> | \u003Cspan class=\"hljs-subst\">{item[\u003Cspan class=\"hljs-string\">&#x27;engagement_rate&#x27;\u003C/span>]:\u003Cspan class=\"hljs-number\">.1\u003C/span>%}\u003C/span> | \u003Cspan class=\"hljs-subst\">{item[\u003Cspan class=\"hljs-string\">&#x27;bounce_rate&#x27;\u003C/span>]:\u003Cspan class=\"hljs-number\">.1\u003C/span>%}\u003C/span> |\\n&quot;\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> report[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>]:\n            markdown += \u003Cspan class=\"hljs-string\">&quot;\\n## 📋 Recommendations\\n\\n&quot;\u003C/span>\n            \n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> rec \u003Cspan class=\"hljs-keyword\">in\u003C/span> report[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>]:\n                severity_emoji = {\u003Cspan class=\"hljs-string\">&#x27;high&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;🔴&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;medium&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;🟡&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;low&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;🟢&#x27;\u003C/span>}\n                markdown += \u003Cspan class=\"hljs-string\">f&quot;### \u003Cspan class=\"hljs-subst\">{severity_emoji.get(rec[\u003Cspan class=\"hljs-string\">&#x27;severity&#x27;\u003C/span>], \u003Cspan class=\"hljs-string\">&#x27;⚪&#x27;\u003C/span>)}\u003C/span> \u003Cspan class=\"hljs-subst\">{rec[\u003Cspan class=\"hljs-string\">&#x27;title&#x27;\u003C/span>]}\u003C/span>\\n\\n&quot;\u003C/span>\n                markdown += \u003Cspan class=\"hljs-string\">f&quot;**Description:** \u003Cspan class=\"hljs-subst\">{rec[\u003Cspan class=\"hljs-string\">&#x27;description&#x27;\u003C/span>]}\u003C/span>\\n\\n&quot;\u003C/span>\n                markdown += \u003Cspan class=\"hljs-string\">f&quot;**Recommended Action:** \u003Cspan class=\"hljs-subst\">{rec[\u003Cspan class=\"hljs-string\">&#x27;action&#x27;\u003C/span>]}\u003C/span>\\n\\n&quot;\u003C/span>\n                \n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> rec.get(\u003Cspan class=\"hljs-string\">&#x27;affected_posts&#x27;\u003C/span>):\n                    markdown += \u003Cspan class=\"hljs-string\">&quot;**Affected Posts:**\\n&quot;\u003C/span>\n                    \u003Cspan class=\"hljs-keyword\">for\u003C/span> post \u003Cspan class=\"hljs-keyword\">in\u003C/span> rec[\u003Cspan class=\"hljs-string\">&#x27;affected_posts&#x27;\u003C/span>]:\n                        markdown += \u003Cspan class=\"hljs-string\">f&quot;- \u003Cspan class=\"hljs-subst\">{post}\u003C/span>\\n&quot;\u003C/span>\n                    markdown += \u003Cspan class=\"hljs-string\">&quot;\\n&quot;\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> markdown\n\n\u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">main\u003C/span>():\n    \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Main analytics function&quot;&quot;&quot;\u003C/span>\n    monitor = ContentAnalyticsMonitor()\n    \n    \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n        report = monitor.generate_performance_report()\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;✅ Performance report generated&quot;\u003C/span>)\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;📊 Analyzed \u003Cspan class=\"hljs-subst\">{report[\u003Cspan class=\"hljs-string\">&#x27;summary&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;total_posts_analyzed&#x27;\u003C/span>]}\u003C/span> posts&quot;\u003C/span>)\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;👀 Total pageviews: \u003Cspan class=\"hljs-subst\">{report[\u003Cspan class=\"hljs-string\">&#x27;summary&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;total_pageviews&#x27;\u003C/span>]:,}\u003C/span>&quot;\u003C/span>)\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;📈 Average per post: \u003Cspan class=\"hljs-subst\">{report[\u003Cspan class=\"hljs-string\">&#x27;summary&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;avg_pageviews_per_post&#x27;\u003C/span>]:\u003Cspan class=\"hljs-number\">.1\u003C/span>f}\u003C/span>&quot;\u003C/span>)\n        \n    \u003Cspan class=\"hljs-keyword\">except\u003C/span> Exception \u003Cspan class=\"hljs-keyword\">as\u003C/span> e:\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;❌ Analytics generation failed: \u003Cspan class=\"hljs-subst\">{e}\u003C/span>&quot;\u003C/span>)\n        \n\u003Cspan class=\"hljs-keyword\">if\u003C/span> __name__ == \u003Cspan class=\"hljs-string\">&quot;__main__&quot;\u003C/span>:\n    main()\n\u003C/code>\u003C/pre>\u003Ch2 id=\"troubleshooting-common-automation-issues\">Troubleshooting Common Automation Issues\u003C/h2>\n\u003Ch3 id=\"cicd-pipeline-failures\">CI/CD Pipeline Failures\u003C/h3>\n\u003Cp>\u003Cstrong>Problem\u003C/strong>: Automation workflows failing due to dependency issues or environment conflicts\u003C/p>\n\u003Cp>\u003Cstrong>Solutions\u003C/strong>:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-yaml\">\u003Cspan class=\"hljs-comment\"># .github/workflows/troubleshooting-fixes.yml\u003C/span>\n\u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Robust\u003C/span> \u003Cspan class=\"hljs-string\">Automation\u003C/span> \u003Cspan class=\"hljs-string\">with\u003C/span> \u003Cspan class=\"hljs-string\">Error\u003C/span> \u003Cspan class=\"hljs-string\">Handling\u003C/span>\n\n\u003Cspan class=\"hljs-attr\">on:\u003C/span>\n  \u003Cspan class=\"hljs-attr\">push:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">branches:\u003C/span> [\u003Cspan class=\"hljs-string\">main\u003C/span>]\n  \u003Cspan class=\"hljs-attr\">workflow_dispatch:\u003C/span>\n\n\u003Cspan class=\"hljs-attr\">jobs:\u003C/span>\n  \u003Cspan class=\"hljs-attr\">content-processing-with-fallbacks:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">runs-on:\u003C/span> \u003Cspan class=\"hljs-string\">ubuntu-latest\u003C/span>\n    \u003Cspan class=\"hljs-attr\">continue-on-error:\u003C/span> \u003Cspan class=\"hljs-literal\">false\u003C/span>\n    \n    \u003Cspan class=\"hljs-attr\">steps:\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Checkout\u003C/span> \u003Cspan class=\"hljs-string\">with\u003C/span> \u003Cspan class=\"hljs-string\">retry\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">nick-invision/retry@v2\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">timeout_minutes:\u003C/span> \u003Cspan class=\"hljs-number\">5\u003C/span>\n          \u003Cspan class=\"hljs-attr\">max_attempts:\u003C/span> \u003Cspan class=\"hljs-number\">3\u003C/span>\n          \u003Cspan class=\"hljs-attr\">command:\u003C/span> \u003Cspan class=\"hljs-string\">|\n            git clone ${{ github.server_url }}/${{ github.repository }}.git .\n\u003C/span>            \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Setup\u003C/span> \u003Cspan class=\"hljs-string\">Node.js\u003C/span> \u003Cspan class=\"hljs-string\">with\u003C/span> \u003Cspan class=\"hljs-string\">caching\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/setup-node@v3\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">node-version:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;18&#x27;\u003C/span>\n          \u003Cspan class=\"hljs-attr\">cache:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;npm&#x27;\u003C/span>\n          \u003Cspan class=\"hljs-attr\">cache-dependency-path:\u003C/span> \u003Cspan class=\"hljs-string\">package-lock.json\u003C/span>\n          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Install\u003C/span> \u003Cspan class=\"hljs-string\">dependencies\u003C/span> \u003Cspan class=\"hljs-string\">with\u003C/span> \u003Cspan class=\"hljs-string\">fallback\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          npm ci --prefer-offline --no-audit || npm install\n\u003C/span>          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Content\u003C/span> \u003Cspan class=\"hljs-string\">validation\u003C/span> \u003Cspan class=\"hljs-string\">with\u003C/span> \u003Cspan class=\"hljs-string\">error\u003C/span> \u003Cspan class=\"hljs-string\">recovery\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          set +e  # Don&#x27;t exit on errors\n\u003C/span>          \n          \u003Cspan class=\"hljs-comment\"># Primary validation\u003C/span>\n          \u003Cspan class=\"hljs-string\">npm\u003C/span> \u003Cspan class=\"hljs-string\">run\u003C/span> \u003Cspan class=\"hljs-string\">validate-content\u003C/span>\n          \u003Cspan class=\"hljs-string\">VALIDATION_EXIT_CODE=$?\u003C/span>\n          \n          \u003Cspan class=\"hljs-string\">if\u003C/span> [ \u003Cspan class=\"hljs-string\">$VALIDATION_EXIT_CODE\u003C/span> \u003Cspan class=\"hljs-string\">-ne\u003C/span> \u003Cspan class=\"hljs-number\">0\u003C/span> ]\u003Cspan class=\"hljs-string\">;\u003C/span> \u003Cspan class=\"hljs-string\">then\u003C/span>\n            \u003Cspan class=\"hljs-string\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;⚠️ Primary validation failed, trying alternative method...&quot;\u003C/span>\n            \n            \u003Cspan class=\"hljs-comment\"># Fallback validation\u003C/span>\n            \u003Cspan class=\"hljs-string\">python3\u003C/span> \u003Cspan class=\"hljs-string\">scripts/basic-validation.py\u003C/span>\n            \u003Cspan class=\"hljs-string\">FALLBACK_EXIT_CODE=$?\u003C/span>\n            \n            \u003Cspan class=\"hljs-string\">if\u003C/span> [ \u003Cspan class=\"hljs-string\">$FALLBACK_EXIT_CODE\u003C/span> \u003Cspan class=\"hljs-string\">-ne\u003C/span> \u003Cspan class=\"hljs-number\">0\u003C/span> ]\u003Cspan class=\"hljs-string\">;\u003C/span> \u003Cspan class=\"hljs-string\">then\u003C/span>\n              \u003Cspan class=\"hljs-string\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;❌ All validation methods failed&quot;\u003C/span>\n              \u003Cspan class=\"hljs-string\">exit\u003C/span> \u003Cspan class=\"hljs-number\">1\u003C/span>\n            \u003Cspan class=\"hljs-string\">else\u003C/span>\n              \u003Cspan class=\"hljs-string\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;✅ Fallback validation succeeded&quot;\u003C/span>\n            \u003Cspan class=\"hljs-string\">fi\u003C/span>\n          \u003Cspan class=\"hljs-string\">else\u003C/span>\n            \u003Cspan class=\"hljs-string\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;✅ Primary validation succeeded&quot;\u003C/span>\n          \u003Cspan class=\"hljs-string\">fi\u003C/span>\n          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Build\u003C/span> \u003Cspan class=\"hljs-string\">with\u003C/span> \u003Cspan class=\"hljs-string\">multiple\u003C/span> \u003Cspan class=\"hljs-string\">attempts\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">nick-invision/retry@v2\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">timeout_minutes:\u003C/span> \u003Cspan class=\"hljs-number\">10\u003C/span>\n          \u003Cspan class=\"hljs-attr\">max_attempts:\u003C/span> \u003Cspan class=\"hljs-number\">3\u003C/span>\n          \u003Cspan class=\"hljs-attr\">command:\u003C/span> \u003Cspan class=\"hljs-string\">|\n            npm run build\n\u003C/span>            \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Upload\u003C/span> \u003Cspan class=\"hljs-string\">artifacts\u003C/span> \u003Cspan class=\"hljs-string\">with\u003C/span> \u003Cspan class=\"hljs-string\">compression\u003C/span>\n        \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">always()\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/upload-artifact@v3\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">build-outputs-${{\u003C/span> \u003Cspan class=\"hljs-string\">github.sha\u003C/span> \u003Cspan class=\"hljs-string\">}}\u003C/span>\n          \u003Cspan class=\"hljs-attr\">path:\u003C/span> \u003Cspan class=\"hljs-string\">|\n            _site/\n            *.log\n            reports/\n\u003C/span>          \u003Cspan class=\"hljs-attr\">retention-days:\u003C/span> \u003Cspan class=\"hljs-number\">30\u003C/span>\n          \u003Cspan class=\"hljs-attr\">if-no-files-found:\u003C/span> \u003Cspan class=\"hljs-string\">warn\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch3 id=\"content-validation-errors\">Content Validation Errors\u003C/h3>\n\u003Cp>\u003Cstrong>Problem\u003C/strong>: False positives in automated content validation\u003C/p>\n\u003Cp>\u003Cstrong>Solutions\u003C/strong>:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-python\">\u003Cspan class=\"hljs-comment\"># scripts/smart-validation.py - Intelligent content validation with context\u003C/span>\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> re\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> yaml\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> pathlib \u003Cspan class=\"hljs-keyword\">import\u003C/span> Path\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">SmartContentValidator\u003C/span>:\n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">__init__\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>):\n        self.load_validation_rules()\n        self.context_cache = {}\n        \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">load_validation_rules\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Load intelligent validation rules&quot;&quot;&quot;\u003C/span>\n        self.rules = {\n            \u003Cspan class=\"hljs-string\">&#x27;spell_check&#x27;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&#x27;custom_dictionary&#x27;\u003C/span>: [\n                    \u003Cspan class=\"hljs-string\">&#x27;markdown&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;github&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;javascript&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;typescript&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;api&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;json&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;yaml&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;css&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;html&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;jsx&#x27;\u003C/span>\n                ],\n                \u003Cspan class=\"hljs-string\">&#x27;context_aware&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;ignore_code_blocks&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>\n            },\n            \u003Cspan class=\"hljs-string\">&#x27;link_validation&#x27;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&#x27;check_internal_only&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;ignore_examples&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;retry_failed_links&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;cache_results&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>\n            },\n            \u003Cspan class=\"hljs-string\">&#x27;content_structure&#x27;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&#x27;flexible_heading_order&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;allow_deep_nesting&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">False\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;require_examples&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">False\u003C/span>\n            }\n        }\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_with_context\u003C/span>(\u003Cspan class=\"hljs-params\">self, content, file_path\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate content with contextual awareness&quot;&quot;&quot;\u003C/span>\n        errors = []\n        warnings = []\n        \n        \u003Cspan class=\"hljs-comment\"># Check if this is a code-heavy post\u003C/span>\n        code_blocks = re.findall(\u003Cspan class=\"hljs-string\">r&#x27;```[\\s\\S]*?```&#x27;\u003C/span>, content)\n        is_technical_post = \u003Cspan class=\"hljs-built_in\">len\u003C/span>(code_blocks) &gt; \u003Cspan class=\"hljs-number\">3\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Adjust validation rules based on content type\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> is_technical_post:\n            \u003Cspan class=\"hljs-comment\"># Relax certain rules for technical content\u003C/span>\n            self.rules[\u003Cspan class=\"hljs-string\">&#x27;spell_check&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;ignore_technical_terms&#x27;\u003C/span>] = \u003Cspan class=\"hljs-literal\">True\u003C/span>\n            self.rules[\u003Cspan class=\"hljs-string\">&#x27;content_structure&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;require_examples&#x27;\u003C/span>] = \u003Cspan class=\"hljs-literal\">False\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Contextual spell checking\u003C/span>\n        spell_errors = self.smart_spell_check(content, is_technical_post)\n        errors.extend(spell_errors)\n        \n        \u003Cspan class=\"hljs-comment\"># Intelligent link validation\u003C/span>\n        link_warnings = self.smart_link_check(content, file_path)\n        warnings.extend(link_warnings)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> {\n            \u003Cspan class=\"hljs-string\">&#x27;errors&#x27;\u003C/span>: errors,\n            \u003Cspan class=\"hljs-string\">&#x27;warnings&#x27;\u003C/span>: warnings,\n            \u003Cspan class=\"hljs-string\">&#x27;context&#x27;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&#x27;is_technical&#x27;\u003C/span>: is_technical_post,\n                \u003Cspan class=\"hljs-string\">&#x27;code_blocks&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">len\u003C/span>(code_blocks),\n                \u003Cspan class=\"hljs-string\">&#x27;estimated_reading_time&#x27;\u003C/span>: self.estimate_reading_time(content)\n            }\n        }\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">smart_spell_check\u003C/span>(\u003Cspan class=\"hljs-params\">self, content, is_technical\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Context-aware spell checking&quot;&quot;&quot;\u003C/span>\n        errors = []\n        \n        \u003Cspan class=\"hljs-comment\"># Remove code blocks for spell checking\u003C/span>\n        content_without_code = re.sub(\u003Cspan class=\"hljs-string\">r&#x27;```[\\s\\S]*?```&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>, content)\n        content_without_inline_code = re.sub(\u003Cspan class=\"hljs-string\">r&#x27;`[^`]+`&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>, content_without_code)\n        \n        \u003Cspan class=\"hljs-comment\"># Use appropriate dictionary based on content type\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> is_technical:\n            \u003Cspan class=\"hljs-comment\"># Use technical dictionary\u003C/span>\n            custom_words = self.rules[\u003Cspan class=\"hljs-string\">&#x27;spell_check&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;custom_dictionary&#x27;\u003C/span>]\n            \u003Cspan class=\"hljs-comment\"># Add more technical terms\u003C/span>\n            custom_words.extend([\u003Cspan class=\"hljs-string\">&#x27;webpack&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;npm&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;yarn&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;docker&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;kubernetes&#x27;\u003C/span>])\n        \n        \u003Cspan class=\"hljs-comment\"># Perform spell check (simplified for example)\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> errors\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">smart_link_check\u003C/span>(\u003Cspan class=\"hljs-params\">self, content, file_path\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Intelligent link validation&quot;&quot;&quot;\u003C/span>\n        warnings = []\n        \n        \u003Cspan class=\"hljs-comment\"># Extract links\u003C/span>\n        links = re.findall(\u003Cspan class=\"hljs-string\">r&#x27;\\[([^\\]]+)\\]\\(([^)]+)\\)&#x27;\u003C/span>, content)\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> link_text, link_url \u003Cspan class=\"hljs-keyword\">in\u003C/span> links:\n            \u003Cspan class=\"hljs-comment\"># Skip example URLs\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">any\u003C/span>(example \u003Cspan class=\"hljs-keyword\">in\u003C/span> link_url \u003Cspan class=\"hljs-keyword\">for\u003C/span> example \u003Cspan class=\"hljs-keyword\">in\u003C/span> [\u003Cspan class=\"hljs-string\">&#x27;example.com&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;localhost&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;127.0.0.1&#x27;\u003C/span>]):\n                \u003Cspan class=\"hljs-keyword\">continue\u003C/span>\n                \n            \u003Cspan class=\"hljs-comment\"># Check internal links more carefully\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> link_url.startswith(\u003Cspan class=\"hljs-string\">&#x27;/&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">or\u003C/span> link_url.startswith(\u003Cspan class=\"hljs-string\">&#x27;../&#x27;\u003C/span>):\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> self.validate_internal_link(link_url, file_path):\n                    warnings.append(\u003Cspan class=\"hljs-string\">f&quot;Internal link may be broken: \u003Cspan class=\"hljs-subst\">{link_url}\u003C/span>&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> warnings\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_internal_link\u003C/span>(\u003Cspan class=\"hljs-params\">self, link_url, current_file\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate internal links with file system checking&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-comment\"># Implementation would check if the referenced file exists\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">True\u003C/span>  \u003Cspan class=\"hljs-comment\"># Simplified for example\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">estimate_reading_time\u003C/span>(\u003Cspan class=\"hljs-params\">self, content\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Estimate reading time in minutes&quot;&quot;&quot;\u003C/span>\n        word_count = \u003Cspan class=\"hljs-built_in\">len\u003C/span>(content.split())\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-built_in\">max\u003C/span>(\u003Cspan class=\"hljs-number\">1\u003C/span>, word_count // \u003Cspan class=\"hljs-number\">200\u003C/span>)  \u003Cspan class=\"hljs-comment\"># Assuming 200 words per minute\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch3 id=\"deployment-and-publishing-issues\">Deployment and Publishing Issues\u003C/h3>\n\u003Cp>\u003Cstrong>Problem\u003C/strong>: Inconsistent deployments or publishing failures\u003C/p>\n\u003Cp>\u003Cstrong>Solutions\u003C/strong>:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-bash\">\u003Cspan class=\"hljs-meta\">#!/bin/bash\u003C/span>\n\u003Cspan class=\"hljs-comment\"># scripts/robust-deployment.sh - Deployment with comprehensive error handling\u003C/span>\n\n\u003Cspan class=\"hljs-built_in\">set\u003C/span> -euo pipefail  \u003Cspan class=\"hljs-comment\"># Exit on any error, undefined variable, or pipe failure\u003C/span>\n\n\u003Cspan class=\"hljs-comment\"># Configuration\u003C/span>\nDEPLOYMENT_ENV=\u003Cspan class=\"hljs-variable\">${1:-staging}\u003C/span>\nMAX_RETRIES=3\nRETRY_DELAY=30\nHEALTH_CHECK_TIMEOUT=300\n\n\u003Cspan class=\"hljs-comment\"># Logging setup\u003C/span>\nLOG_FILE=\u003Cspan class=\"hljs-string\">&quot;deployment-\u003Cspan class=\"hljs-subst\">$(date +%Y%m%d-%H%M%S)\u003C/span>.log&quot;\u003C/span>\n\u003Cspan class=\"hljs-built_in\">exec\u003C/span> 1&gt; &gt;(\u003Cspan class=\"hljs-built_in\">tee\u003C/span> -a \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$LOG_FILE\u003C/span>&quot;\u003C/span>)\n\u003Cspan class=\"hljs-built_in\">exec\u003C/span> 2&gt;&amp;1\n\n\u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;🚀 Starting deployment to \u003Cspan class=\"hljs-variable\">$DEPLOYMENT_ENV\u003C/span> environment&quot;\u003C/span>\n\u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;📝 Logging to: \u003Cspan class=\"hljs-variable\">$LOG_FILE\u003C/span>&quot;\u003C/span>\n\n\u003Cspan class=\"hljs-comment\"># Pre-deployment checks\u003C/span>\n\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-title\">pre_deployment_checks\u003C/span>\u003C/span>() {\n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;🔍 Running pre-deployment checks...&quot;\u003C/span>\n    \n    \u003Cspan class=\"hljs-comment\"># Check required environment variables\u003C/span>\n    required_vars=(\u003Cspan class=\"hljs-string\">&quot;GITHUB_TOKEN&quot;\u003C/span> \u003Cspan class=\"hljs-string\">&quot;DEPLOYMENT_KEY&quot;\u003C/span> \u003Cspan class=\"hljs-string\">&quot;CDN_TOKEN&quot;\u003C/span>)\n    \u003Cspan class=\"hljs-keyword\">for\u003C/span> var \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">${required_vars[@]}\u003C/span>&quot;\u003C/span>; \u003Cspan class=\"hljs-keyword\">do\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> [[ -z \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">${!var:-}\u003C/span>&quot;\u003C/span> ]]; \u003Cspan class=\"hljs-keyword\">then\u003C/span>\n            \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;❌ Required environment variable \u003Cspan class=\"hljs-variable\">$var\u003C/span> is not set&quot;\u003C/span>\n            \u003Cspan class=\"hljs-built_in\">exit\u003C/span> 1\n        \u003Cspan class=\"hljs-keyword\">fi\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">done\u003C/span>\n    \n    \u003Cspan class=\"hljs-comment\"># Check disk space\u003C/span>\n    available_space=$(\u003Cspan class=\"hljs-built_in\">df\u003C/span> / | awk \u003Cspan class=\"hljs-string\">&#x27;NR==2{print $4}&#x27;\u003C/span>)\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> [[ \u003Cspan class=\"hljs-variable\">$available_space\u003C/span> -lt 1048576 ]]; \u003Cspan class=\"hljs-keyword\">then\u003C/span>  \u003Cspan class=\"hljs-comment\"># Less than 1GB\u003C/span>\n        \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;⚠️ Low disk space: \u003Cspan class=\"hljs-variable\">${available_space}\u003C/span>KB available&quot;\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">fi\u003C/span>\n    \n    \u003Cspan class=\"hljs-comment\"># Validate build artifacts\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> [[ ! -d \u003Cspan class=\"hljs-string\">&quot;_site&quot;\u003C/span> ]] || [[ -z \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-subst\">$(ls -A _site)\u003C/span>&quot;\u003C/span> ]]; \u003Cspan class=\"hljs-keyword\">then\u003C/span>\n        \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;❌ Build artifacts not found or empty&quot;\u003C/span>\n        \u003Cspan class=\"hljs-built_in\">exit\u003C/span> 1\n    \u003Cspan class=\"hljs-keyword\">fi\u003C/span>\n    \n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;✅ Pre-deployment checks passed&quot;\u003C/span>\n}\n\n\u003Cspan class=\"hljs-comment\"># Deploy with retry mechanism\u003C/span>\n\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-title\">deploy_with_retry\u003C/span>\u003C/span>() {\n    \u003Cspan class=\"hljs-built_in\">local\u003C/span> deployment_command=\u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$1\u003C/span>&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">local\u003C/span> attempt=1\n    \n    \u003Cspan class=\"hljs-keyword\">while\u003C/span> [[ \u003Cspan class=\"hljs-variable\">$attempt\u003C/span> -le \u003Cspan class=\"hljs-variable\">$MAX_RETRIES\u003C/span> ]]; \u003Cspan class=\"hljs-keyword\">do\u003C/span>\n        \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;🎯 Deployment attempt \u003Cspan class=\"hljs-variable\">$attempt\u003C/span>/\u003Cspan class=\"hljs-variable\">$MAX_RETRIES\u003C/span>&quot;\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">eval\u003C/span> \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$deployment_command\u003C/span>&quot;\u003C/span>; \u003Cspan class=\"hljs-keyword\">then\u003C/span>\n            \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;✅ Deployment successful on attempt \u003Cspan class=\"hljs-variable\">$attempt\u003C/span>&quot;\u003C/span>\n            \u003Cspan class=\"hljs-built_in\">return\u003C/span> 0\n        \u003Cspan class=\"hljs-keyword\">else\u003C/span>\n            \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;❌ Deployment attempt \u003Cspan class=\"hljs-variable\">$attempt\u003C/span> failed&quot;\u003C/span>\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> [[ \u003Cspan class=\"hljs-variable\">$attempt\u003C/span> -lt \u003Cspan class=\"hljs-variable\">$MAX_RETRIES\u003C/span> ]]; \u003Cspan class=\"hljs-keyword\">then\u003C/span>\n                \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;⏳ Waiting \u003Cspan class=\"hljs-variable\">${RETRY_DELAY}\u003C/span>s before retry...&quot;\u003C/span>\n                \u003Cspan class=\"hljs-built_in\">sleep\u003C/span> \u003Cspan class=\"hljs-variable\">$RETRY_DELAY\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">fi\u003C/span>\n            \n            ((attempt++))\n        \u003Cspan class=\"hljs-keyword\">fi\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">done\u003C/span>\n    \n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;❌ All deployment attempts failed&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">return\u003C/span> 1\n}\n\n\u003Cspan class=\"hljs-comment\"># Health check with timeout\u003C/span>\n\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-title\">health_check\u003C/span>\u003C/span>() {\n    \u003Cspan class=\"hljs-built_in\">local\u003C/span> url=\u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$1\u003C/span>&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">local\u003C/span> \u003Cspan class=\"hljs-built_in\">timeout\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$2\u003C/span>&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">local\u003C/span> start_time=$(\u003Cspan class=\"hljs-built_in\">date\u003C/span> +%s)\n    \n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;🏥 Running health check on \u003Cspan class=\"hljs-variable\">$url\u003C/span> (timeout: \u003Cspan class=\"hljs-variable\">${timeout}\u003C/span>s)&quot;\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">while\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>; \u003Cspan class=\"hljs-keyword\">do\u003C/span>\n        current_time=$(\u003Cspan class=\"hljs-built_in\">date\u003C/span> +%s)\n        elapsed=$((current_time - start_time))\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> [[ \u003Cspan class=\"hljs-variable\">$elapsed\u003C/span> -ge \u003Cspan class=\"hljs-variable\">$timeout\u003C/span> ]]; \u003Cspan class=\"hljs-keyword\">then\u003C/span>\n            \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;❌ Health check timed out after \u003Cspan class=\"hljs-variable\">${timeout}\u003C/span>s&quot;\u003C/span>\n            \u003Cspan class=\"hljs-built_in\">return\u003C/span> 1\n        \u003Cspan class=\"hljs-keyword\">fi\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> curl -s -f \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$url\u003C/span>&quot;\u003C/span> &gt; /dev/null; \u003Cspan class=\"hljs-keyword\">then\u003C/span>\n            \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;✅ Health check passed after \u003Cspan class=\"hljs-variable\">${elapsed}\u003C/span>s&quot;\u003C/span>\n            \u003Cspan class=\"hljs-built_in\">return\u003C/span> 0\n        \u003Cspan class=\"hljs-keyword\">fi\u003C/span>\n        \n        \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;⏳ Waiting for service to be available... (\u003Cspan class=\"hljs-variable\">${elapsed}\u003C/span>s elapsed)&quot;\u003C/span>\n        \u003Cspan class=\"hljs-built_in\">sleep\u003C/span> 10\n    \u003Cspan class=\"hljs-keyword\">done\u003C/span>\n}\n\n\u003Cspan class=\"hljs-comment\"># Rollback mechanism\u003C/span>\n\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-title\">rollback_deployment\u003C/span>\u003C/span>() {\n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;🔄 Initiating rollback...&quot;\u003C/span>\n    \n    \u003Cspan class=\"hljs-comment\"># Get previous deployment ID\u003C/span>\n    previous_deployment=$(git \u003Cspan class=\"hljs-built_in\">log\u003C/span> --format=\u003Cspan class=\"hljs-string\">&quot;%H&quot;\u003C/span> -n 2 | \u003Cspan class=\"hljs-built_in\">tail\u003C/span> -n 1)\n    \n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> [[ -n \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$previous_deployment\u003C/span>&quot;\u003C/span> ]]; \u003Cspan class=\"hljs-keyword\">then\u003C/span>\n        \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;📦 Rolling back to deployment: \u003Cspan class=\"hljs-variable\">$previous_deployment\u003C/span>&quot;\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Restore previous build\u003C/span>\n        git checkout \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$previous_deployment\u003C/span>&quot;\u003C/span> -- _site/\n        \n        \u003Cspan class=\"hljs-comment\"># Redeploy\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> deploy_with_retry \u003Cspan class=\"hljs-string\">&quot;npm run deploy:\u003Cspan class=\"hljs-variable\">$DEPLOYMENT_ENV\u003C/span>&quot;\u003C/span>; \u003Cspan class=\"hljs-keyword\">then\u003C/span>\n            \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;✅ Rollback completed successfully&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">else\u003C/span>\n            \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;❌ Rollback failed - manual intervention required&quot;\u003C/span>\n            \u003Cspan class=\"hljs-built_in\">exit\u003C/span> 1\n        \u003Cspan class=\"hljs-keyword\">fi\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">else\u003C/span>\n        \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;❌ No previous deployment found for rollback&quot;\u003C/span>\n        \u003Cspan class=\"hljs-built_in\">exit\u003C/span> 1\n    \u003Cspan class=\"hljs-keyword\">fi\u003C/span>\n}\n\n\u003Cspan class=\"hljs-comment\"># Main deployment process\u003C/span>\n\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-title\">main\u003C/span>\u003C/span>() {\n    \u003Cspan class=\"hljs-comment\"># Trap errors and perform rollback\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">trap\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;echo &quot;💥 Deployment failed - initiating rollback&quot;; rollback_deployment&#x27;\u003C/span> ERR\n    \n    \u003Cspan class=\"hljs-comment\"># Pre-deployment validation\u003C/span>\n    pre_deployment_checks\n    \n    \u003Cspan class=\"hljs-comment\"># Backup current state\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;💾 Creating deployment backup...&quot;\u003C/span>\n    tar -czf \u003Cspan class=\"hljs-string\">&quot;backup-\u003Cspan class=\"hljs-subst\">$(date +%Y%m%d-%H%M%S)\u003C/span>.tar.gz&quot;\u003C/span> _site/\n    \n    \u003Cspan class=\"hljs-comment\"># Deploy based on environment\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">case\u003C/span> \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$DEPLOYMENT_ENV\u003C/span>&quot;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span>\n        \u003Cspan class=\"hljs-string\">&quot;staging&quot;\u003C/span>)\n            DEPLOY_URL=\u003Cspan class=\"hljs-string\">&quot;https://staging.markdowntools.com&quot;\u003C/span>\n            deploy_with_retry \u003Cspan class=\"hljs-string\">&quot;npm run deploy:staging&quot;\u003C/span>\n            ;;\n        \u003Cspan class=\"hljs-string\">&quot;production&quot;\u003C/span>)\n            DEPLOY_URL=\u003Cspan class=\"hljs-string\">&quot;https://blog.markdowntools.com&quot;\u003C/span>\n            deploy_with_retry \u003Cspan class=\"hljs-string\">&quot;npm run deploy:production&quot;\u003C/span>\n            ;;\n        *)\n            \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;❌ Unknown deployment environment: \u003Cspan class=\"hljs-variable\">$DEPLOYMENT_ENV\u003C/span>&quot;\u003C/span>\n            \u003Cspan class=\"hljs-built_in\">exit\u003C/span> 1\n            ;;\n    \u003Cspan class=\"hljs-keyword\">esac\u003C/span>\n    \n    \u003Cspan class=\"hljs-comment\"># Post-deployment verification\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;🔍 Verifying deployment...&quot;\u003C/span>\n    health_check \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$DEPLOY_URL\u003C/span>&quot;\u003C/span> \u003Cspan class=\"hljs-variable\">$HEALTH_CHECK_TIMEOUT\u003C/span>\n    \n    \u003Cspan class=\"hljs-comment\"># Clean up old backups (keep last 5)\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;🧹 Cleaning up old backups...&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">ls\u003C/span> -t backup-*.tar.gz | \u003Cspan class=\"hljs-built_in\">tail\u003C/span> -n +6 | xargs -r \u003Cspan class=\"hljs-built_in\">rm\u003C/span>\n    \n    \u003Cspan class=\"hljs-comment\"># Notify success\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;🎉 Deployment to \u003Cspan class=\"hljs-variable\">$DEPLOYMENT_ENV\u003C/span> completed successfully!&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;🌐 Available at: \u003Cspan class=\"hljs-variable\">$DEPLOY_URL\u003C/span>&quot;\u003C/span>\n    \n    \u003Cspan class=\"hljs-comment\"># Send notification\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> [[ -n \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">${SLACK_WEBHOOK:-}\u003C/span>&quot;\u003C/span> ]]; \u003Cspan class=\"hljs-keyword\">then\u003C/span>\n        curl -X POST -H \u003Cspan class=\"hljs-string\">&#x27;Content-type: application/json&#x27;\u003C/span> \\\n            --data \u003Cspan class=\"hljs-string\">&quot;{\\&quot;text\\&quot;:\\&quot;✅ Deployment to \u003Cspan class=\"hljs-variable\">$DEPLOYMENT_ENV\u003C/span> successful: \u003Cspan class=\"hljs-variable\">$DEPLOY_URL\u003C/span>\\&quot;}&quot;\u003C/span> \\\n            \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$SLACK_WEBHOOK\u003C/span>&quot;\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">fi\u003C/span>\n}\n\n\u003Cspan class=\"hljs-comment\"># Execute main function\u003C/span>\nmain \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$@\u003C/span>&quot;\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch2 id=\"conclusion\">Conclusion\u003C/h2>\n\u003Cp>Markdown automation workflows represent a transformative approach to content management and documentation processes, enabling teams to maintain high-quality standards while scaling their content operations efficiently. By implementing comprehensive CI/CD pipelines, automated validation systems, and intelligent publishing workflows, organizations can create robust content ecosystems that support rapid iteration, consistent quality assurance, and seamless integration with modern development practices.\u003C/p>\n\u003Cp>The key to successful Markdown automation lies in balancing comprehensive coverage with practical implementation, ensuring that automated systems enhance rather than complicate content creation workflows. Whether you&#39;re building documentation systems, content publishing platforms, or technical writing workflows, the automation techniques covered in this guide provide the foundation for creating scalable, maintainable, and reliable content management systems.\u003C/p>\n\u003Cp>Remember to start with basic automation and gradually add sophistication, monitor your automation systems for reliability and performance, and continuously refine your workflows based on team feedback and changing requirements. With proper implementation of Markdown automation workflows, your organization can achieve unprecedented efficiency in content creation, quality assurance, and publishing while maintaining the flexibility and simplicity that makes Markdown such a valuable content creation format.\u003C/p>\n",[15,19,22,25,28,31,34,37,40,43,46],{"id":16,"text":17,"level":18},"why-master-markdown-automation-workflows","Why Master Markdown Automation Workflows?",2,{"id":20,"text":21,"level":18},"foundation-automation-architecture","Foundation Automation Architecture",{"id":23,"text":24,"level":18},"advanced-automation-techniques","Advanced Automation Techniques",{"id":26,"text":27,"level":18},"development-setup","Development Setup",{"id":29,"text":30,"level":18},"code-style-guidelines","Code Style Guidelines",{"id":32,"text":33,"level":18},"documentation-standards","Documentation Standards",{"id":35,"text":36,"level":18},"need-help","Need Help?",{"id":38,"text":39,"level":18},"integration-with-modern-development-workflows","Integration with Modern Development Workflows",{"id":41,"text":42,"level":18},"monitoring-and-analytics-integration","Monitoring and Analytics Integration",{"id":44,"text":45,"level":18},"troubleshooting-common-automation-issues","Troubleshooting Common Automation Issues",{"id":47,"text":48,"level":18},"conclusion","Conclusion",[],[51,59,67],{"slug":52,"title":53,"description":54,"excerpt":55,"date":56,"category":9,"author":10,"keywords":57,"readingMinutes":58},"markdown-dynamic-content-generation-automation-workflows-complete-guide","Markdown Dynamic Content Generation and Automation Workflows: Complete Guide for Automated Documentation, Template Systems, and Content Pipeline Management","Master dynamic content generation in Markdown with comprehensive automation workflows, template engines, data-driven documentation systems, and intelligent content pipeline management for scalable technical writing.","Advanced Markdown dynamic content generation and automation workflows enable systematic creation of data-driven documentation, template-based content systems, and intelligent content pipelines…","2025-12-22","markdown automation, dynamic content generation markdown, markdown templates, automated documentation markdown, content pipeline markdown, markdown workflows, data driven documentation, template engines markdown",37,{"slug":60,"title":61,"description":62,"excerpt":63,"date":64,"category":9,"author":10,"keywords":65,"readingMinutes":66},"markdown-documentation-site-generators-complete-guide","Markdown Documentation Site Generators: Complete Guide for Modern Documentation Workflows and Static Site Generation","Master advanced Markdown documentation site generators including Jekyll, Hugo, MkDocs, and Docusaurus. Learn site generation workflows, theme customization, plugin systems, and deployment strategies for professional documentation platforms.","Advanced Markdown documentation site generators enable sophisticated content management workflows that transform simple Markdown files into comprehensive documentation platforms with professional…","2025-12-02","markdown documentation generators, jekyll markdown, hugo markdown, mkdocs, docusaurus markdown, static site generators, documentation workflows, markdown site themes, documentation deployment",27,{"slug":68,"title":69,"description":70,"excerpt":71,"date":72,"category":9,"author":10,"keywords":73,"readingMinutes":74},"markdown-diagram-workflows-integration-complete-guide","Markdown Diagram Workflows and Integration: Complete Guide for Visual Documentation and Automated Diagram Generation","Master advanced Markdown diagram workflows with Mermaid, PlantUML, and D2. Learn automated diagram generation, version control integration, CI/CD pipelines, and cross-platform compatibility for professional visual documentation.","Advanced Markdown diagram workflows and integration techniques enable sophisticated visual documentation that combines the simplicity of text-based markup with powerful automated diagram…","2025-11-03","markdown diagrams, mermaid diagrams, plantuml markdown, d2 diagrams, diagram automation, visual documentation, markdown workflows, diagram version control, automated diagrams",16,1792184942304]