diff --git a/.github/workflows/update-sponsors.yml b/.github/workflows/update-sponsors.yml new file mode 100644 index 000000000..0bf07b582 --- /dev/null +++ b/.github/workflows/update-sponsors.yml @@ -0,0 +1,41 @@ +name: Update Sponsors + +on: + workflow_dispatch: # allow manual run + schedule: + - cron: '0 */3 * * *' # every 3 hours + +env: + SPONSOR_SHEET_API_KEY: ${{ secrets.SPONSOR_SHEET_API_KEY }} + SPONSOR_SHEET_ID: ${{ secrets.SPONSOR_SHEET_ID }} + +jobs: + update-sponsors: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v3 + with: + node-version: 18 + - uses: pnpm/action-setup@v2.2.2 + with: + version: 7.13.4 + - name: Update the Sponsors + run: | + pnpm install + node bin/roadmap-ads.cjs + - name: Create PR + uses: peter-evans/create-pull-request@v4 + with: + delete-branch: false + branch: "update-sponsors" + base: "master" + labels: | + sponsors + automated pr + reviewers: kamranahmedse + commit-message: "chore: update sponsors" + title: "Upgrade Sponsor Banners" + body: | + Updates sponsor banners. + Please review the changes and merge if everything looks good. diff --git a/bin/roadmap-ads.cjs b/bin/roadmap-ads.cjs new file mode 100644 index 000000000..d55acd560 --- /dev/null +++ b/bin/roadmap-ads.cjs @@ -0,0 +1,109 @@ +const path = require('path'); +const fs = require('fs'); +const yaml = require('js-yaml'); + +const apiKey = process.env.SPONSOR_SHEET_API_KEY; +const sheetId = process.env.SPONSOR_SHEET_ID; + +if (!apiKey || !sheetId) { + console.error('Missing API key or sheet ID'); + process.exit(1); +} + +const sheetRange = 'A3:I1001'; +const sheetUrl = `https://sheets.googleapis.com/v4/spreadsheets/${sheetId}/values/${sheetRange}?key=${apiKey}`; + +function populateRoadmapAds({ + roadmapUrl, + company, + redirectUrl, + imageUrl, + adTitle, + adDescription, + startDate, + endDate, + isActive, +}) { + const isConfiguredActive = isActive.toLowerCase() === 'yes'; + + const currentDate = new Date(); + const isDateInRange = currentDate >= new Date(startDate) && currentDate <= new Date(endDate); + const shouldShowAd = isConfiguredActive && isDateInRange; + + // get id from the roadmap URL + const roadmapId = roadmapUrl + .split('/') + .pop() + .replace(/\?.+?$/, ''); + + const roadmapFilePath = path.join(__dirname, '../src/data/roadmaps', `${roadmapId}/${roadmapId}.md`); + + if (!fs.existsSync(roadmapFilePath)) { + console.error(`Roadmap file not found: ${roadmapFilePath}`); + process.exit(1); + } + + console.log(`Updating roadmap: ${roadmapId}`); + const roadmapFileContent = fs.readFileSync(roadmapFilePath, 'utf8'); + + const frontMatterRegex = /---\n([\s\S]*?)\n---/; + + const existingFrontmatter = roadmapFileContent.match(frontMatterRegex)[1]; + const contentWithoutFrontmatter = roadmapFileContent.replace(frontMatterRegex, ``).trim(); + + const yamlObject = yaml.load(existingFrontmatter); + + if (shouldShowAd) { + yamlObject.sponsor = { + url: redirectUrl, + title: adTitle, + imageUrl, + description: adDescription, + event: { + category: 'SponsorClick', + action: `${company} Redirect`, + label: `Clicked ${company} Link`, + }, + }; + } else { + delete yamlObject.sponsor; + } + + const newFrontmatter = yaml.dump(yamlObject, { lineWidth: 10000, forceQuotes: true, quotingType: '"' }); + const newContent = `---\n${newFrontmatter}---\n\n${contentWithoutFrontmatter}`; + + fs.writeFileSync(roadmapFilePath, newContent, 'utf8'); +} + +fetch(sheetUrl) + .then((res) => res.json()) + .then((rawData) => { + const rows = rawData.values; + + rows.map((row) => { + // prettier-ignore + const [ + roadmapUrl, + company, + redirectUrl, + imageUrl, + adTitle, + adDescription, + startDate, + endDate, + isActive, + ] = row; + + populateRoadmapAds({ + roadmapUrl, + company, + redirectUrl, + imageUrl, + adTitle, + adDescription, + startDate, + endDate, + isActive, + }); + }); + }); diff --git a/package.json b/package.json index 25fb7a276..bae4071cc 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "@playwright/test": "^1.31.1", "@tailwindcss/typography": "^0.5.9", "gh-pages": "^5.0.0", - "json-to-pretty-yaml": "^1.2.2", + "js-yaml": "^4.1.0", "markdown-it": "^13.0.1", "prettier": "^2.8.4", "prettier-plugin-astro": "^0.8.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7ea9cba30..7a31fcdc7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,7 @@ specifiers: astro: ^2.0.15 astro-compress: ^1.1.34 gh-pages: ^5.0.0 + js-yaml: ^4.1.0 json-to-pretty-yaml: ^1.2.2 markdown-it: ^13.0.1 node-html-parser: ^6.1.5 @@ -33,6 +34,7 @@ devDependencies: '@playwright/test': 1.31.1 '@tailwindcss/typography': 0.5.9_tailwindcss@3.2.7 gh-pages: 5.0.0 + js-yaml: 4.1.0 json-to-pretty-yaml: 1.2.2 markdown-it: 13.0.1 prettier: 2.8.4 @@ -2719,7 +2721,6 @@ packages: hasBin: true dependencies: argparse: 2.0.1 - dev: false /jsesc/2.5.2: resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} diff --git a/src/data/roadmaps/backend/backend.md b/src/data/roadmaps/backend/backend.md index 37d7d20c7..0100ad508 100644 --- a/src/data/roadmaps/backend/backend.md +++ b/src/data/roadmaps/backend/backend.md @@ -13,13 +13,13 @@ dimensions: height: 2840.4 sponsor: url: "https://www.fermyon.com/spin?utm_source=backend&utm_medium=banner&utm_campaign=roadmap-sh" - title: "Severless Backend Apps" + title: "Serverless Backend Apps" imageUrl: "https://i.imgur.com/2ONZopb.jpg" description: "Go from blinking cursor to deployed serverless Backend apps in 66 seconds with Fermyon Cloud." event: category: "SponsorClick" - action: "Ambassador Product Redirect" - label: "Clicked Ambassador Product Link" + action: "Fermyon Redirect" + label: "Clicked Fermyon Link" schema: headline: "Backend Developer Roadmap" description: "Learn how to become a Backend Developer with this interactive step by step guide in 2023. We also have resources and short descriptions attached to the roadmap items so you can get everything you want to learn in one place." diff --git a/src/data/roadmaps/devops/devops.md b/src/data/roadmaps/devops/devops.md index 3ccdb0900..c3e14a9db 100644 --- a/src/data/roadmaps/devops/devops.md +++ b/src/data/roadmaps/devops/devops.md @@ -24,8 +24,8 @@ sponsor: description: "Get your Kubernetes API Gateway up and running in 5 minutes with Ambassador Edge Stack!" event: category: "SponsorClick" - action: "Ambassador Product Redirect" - label: "Clicked Ambassador Product Link" + action: "Ambassador Redirect" + label: "Clicked Ambassador Link" seo: title: "DevOps Roadmap: Learn to become a DevOps Engineer or SRE" description: "Community driven, articles, resources, guides, interview questions, quizzes for DevOps. Learn to become a modern DevOps engineer by following the steps, skills, resources and guides listed in this roadmap." diff --git a/src/data/roadmaps/javascript/javascript.md b/src/data/roadmaps/javascript/javascript.md index 689fc7fcf..f716a05b6 100644 --- a/src/data/roadmaps/javascript/javascript.md +++ b/src/data/roadmaps/javascript/javascript.md @@ -15,11 +15,11 @@ sponsor: url: "https://www.fermyon.com/spin?utm_source=javascript&utm_medium=banner&utm_campaign=roadmap-sh" title: "Serverless JavaScript Apps" imageUrl: "https://i.imgur.com/2ONZopb.jpg" - description: "Go from blinking cursor to deployed serverless JavaScript apps in 66 seconds with Fermyon Cloud." + description: "Go from blinking cursor to deployed serverless JavaScript apps in 66 seconds with Fermyon Cloud" event: category: "SponsorClick" - action: "Fermyon Product Redirect" - label: "Clicked Fermyon Product Link" + action: "Fermyon Redirect" + label: "Clicked Fermyon Link" schema: headline: "JavaScript Roadmap" description: "Learn JavaScript with this interactive step by step guide in 2023. We also have resources and short descriptions attached to the roadmap items so you can get everything you want to learn in one place." diff --git a/src/data/roadmaps/python/python.md b/src/data/roadmaps/python/python.md index 19f299610..8578a92ad 100644 --- a/src/data/roadmaps/python/python.md +++ b/src/data/roadmaps/python/python.md @@ -17,8 +17,8 @@ sponsor: description: "Go from blinking cursor to deployed serverless Python apps in 66 seconds with Fermyon Cloud." event: category: "SponsorClick" - action: "Ambassador Product Redirect" - label: "Clicked Ambassador Product Link" + action: "Fermyon Redirect" + label: "Clicked Fermyon Link" schema: headline: "Python Roadmap" description: "Learn Python with this interactive step by step guide in 2023. We also have resources and short descriptions attached to the roadmap items so you can get everything you want to learn in one place."