+2

Tạo GitHub Profile tự động thay đổi content

Trong bài viết này, chúng ta sẽ thiết lập một workflow GitHub Action để tự động cập nhật file README.md của bạn mỗi khi có một schedule hoặc khi bạn chạy workflow thủ công. Hướng dẫn này sẽ bao gồm việc sử dụng Node.js để cập nhật nội dung profile GitHub của bạn một cách động dựa trên thời gian hiện tại và một câu trích dẫn ngẫu nhiên từ API.

Ví dụ, ai đó vào trang cá nhân github của bạn sẽ hiển thị message "Good morning", "Good afternoon" tùy thuộc vào khung giờ. Ngoài ra cứ 2 tiếng một lần, một quote mới sẽ được tự động update trên profile github của mình như tài khoản github kenini1805 này mình đã setup. Đây chỉ là ví dụ đơn giản, bạn có thể làm nhiều thứ hay ho hơn nữa

Viết bài trong 5 phút trong lúc đợi build production 😴😴

1. Chuẩn bị thư mục

Trong thư mục dự án của bạn, cần chuẩn bị các file sau:

  • .github/workflows/update-readme.yml: chứa cấu hình workflow cho GitHub Actions.
  • index.js: file JavaScript để tạo content cho profile của bạn.
  • package.jsonpackage-lock.json: các file chứa thông tin về các dependencies

Cấu trúc thư mục

.
├── .github/
│   └── workflows/
│       └── update-readme.yml
├── .gitignore
├── README.md
├── index.js
├── package.json
└── package-lock.json

2. Thiết lập GitHub Actions

Tạo file .github/workflows/update-readme.yml với nội dung sau:

name: Update Readme

on:
  workflow_dispatch:
  schedule:
    - cron:  '0 2,4,6,8,9,10,11,12,13,14,15,16,17,18,20,22 * * *'

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - name: Use Node.js
      uses: actions/setup-node@v2
      with:
        node-version: '18'
    - name: Install dependencies
      run: |
        npm ci
    - name: Run build command
      run: |-
        npm run build
    - name: Commit and push if changed
      run: |-
        git add .
        git diff
        git config --global user.email "huusu1996@gmail.com"
        git config --global user.name "Kenini1805"
        git commit -m "docs: update greeting and quote" -a || echo "No changes to commit"
        git push

Giải thích:

  • schedule: Workflow sẽ chạy theo lịch trình định trước (ví dụ mỗi 2 giờ).
  • workflow_dispatch: Cho phép bạn chạy workflow thủ công từ GitHub Actions.
  • build job: Workflow sẽ chạy trên Ubuntu và sử dụng Node.js để build profile

Bước 3: Tạo nội dung thay đổi hàng giờ với Node.js

Tạo file index.js để tạo content cho README.md.

const axios = require("axios");
const fs = require("fs");
const md = require("markdown-it")({
  html: true, // Enable HTML tags in source
  breaks: false, // Convert '\n' in paragraphs into <br>
});

const TIMEZONE_OFFSET = 7;
const QUOTES_API = "https://zenquotes.io/api/quotes";

(async () => {
  const { today, hour } = getCurrentTime();
  const greetings = generateGreetings(hour);
  const { quote, author } = await getQuotes(hour);

  const text = `### ${greetings}
  <h2>I'm Michael, a Backend Engineer. <img src="https://media.giphy.com/media/mGcNjsfWAjY5AEZNw6/giphy.gif" width="50"></h2>

  ## <img src="https://emojis.slackmojis.com/emojis/images/1588315024/8823/hyperkitty.gif?1588315024" width="30" /> SKILL
  [<img align="right" width="50%" src="https://github-readme-stats.vercel.app/api?username=Kenini1805&show_icons=true&theme=synthwave">](https://metrics.lecoq.io/ouuan?template=classic)
  
  - Understands \`OOP\` well
  - \`HTML\`, \`CSS\`, \`Bootstrap\`: proficient
  - Strong skills in \`JQuery\`, \`MySQL\`, \`PHP\`
  - Excellent with the \`Laravel\` framework for web design
  - Proficient with \`Git\`
  - Learning the \`Agile\` mindset
  - Knowledge of \`Vue.js\` and \`Vuex\`
  - Skill in \`Unit Testing\`
  - Experience in manual and \`automated deployment\`
  - Familiar with \`AWS\`
  
  ## <img src="https://emojis.slackmojis.com/emojis/images/1643515721/17468/homersimpson-pbjdance.gif?1643515721" width="30" /> CERTIFICATES
  <img src="https://images.viblo.asia/1f5d99d1-8cb7-4d82-a627-d6934d20d94b.png" width="100" />
  
  ## <img src="https://images.viblo.asia/a22cc9ed-e446-4eae-ad55-1ddf8afbaa54.gif" width="30" /> CONTRIBUTIONS
  [<img align="right" width="50%" src="https://github-readme-stats.vercel.app/api/top-langs/?username=Kenini1805&show_icons=true&theme=synthwave&layout=compact">](https://metrics.lecoq.io/ouuan?template=classic)
  
  #### 06/2020
  **Contributor at Laravel**: 
  - https://github.com/laravel/framework/pull/33278
  - https://github.com/laravel/framework/pull/49669

  #### 2019
  **Contributor at Chat++**: 
  - https://github.com/wataridori/chatpp/graphs/contributors
  
  #### Present
  Owner of packages \`Laravel monitoring\` and \`Nginx monitoring\`
  - https://github.com/AvengersCodeLovers/laravel-log-monitoring
  - https://github.com/AvengersCodeLovers/nginx-log-monitoring
  
  ## <img src="https://i.imgur.com/g4uAchW.gif" width="30" /> ABOUT ME
  💬 Ask me anything: [chillwithsu.com](https://chillwithsu.com/)
  ## Quote of the day:
  *"${quote}"* <br>
  — ${author}
  
  ⚡ Fun fact: ***No pain, no gain***
`;

  const content = md.renderInline(text);
  generateFile(content);

  /* Timestamp */
  console.log(`⏳ Running at ${today} UTC +0${TIMEZONE_OFFSET}:00`);
})();

function getCurrentTime() {
  const today = new Date();
  today.setHours(today.getHours() + TIMEZONE_OFFSET);
  const hour = today.getHours();
  const minute = today.getMinutes();
  // check if the hour >= 24
  if (hour >= 24) {
    return Math.abs(24 - hour);
  }
  return {
    today,
    hour,
    minute
  };
}

function isWeekend(date = getCurrentTime().today) {
  return date.getDay() === 6 || date.getDay() === 0;
}

function generateGreetings(time) {
  const goodMorning = "Good morning ☀️";
  const goodAfternoon = "Good afternoon 👋";
  const goodEvening = "Good evening ☕";
  const goodNight = "Good night 😴";
  const happyWeekend = "Happy weekend 🏝️";

  if (isWeekend()) {
    return happyWeekend;
  }
  if (time >= 4 && time < 11) {
    return goodMorning;
  }
  if (time >= 11 && time < 16) {
    return goodAfternoon;
  }
  if (time >= 16 && time < 23) {
    return goodEvening;
  }
  return goodNight;
}

async function getQuotes(time) {
    return await axios.get(QUOTES_API).then((response) => {
        if (response.data.length === 0) {
          return {
            quote: "There is no result without struggle, there is no struggle without sacrifice.",
            author: "Me",
          };
        }
        const { q, a } = response.data[0];
        return {
          quote: q,
          author: a,
        };
      });
}

function generateFile(contents) {
  const targetFile = "README.md";
  fs.writeFile(targetFile, contents, function (err) {
    if (err) return console.log(`⛔ [FAILED]: ${err}`);
    console.log("✅ [SUCCESS]: README.md has been generated.");
  });
}

Giải thích:

  • getCurrentTime: Lấy giờ hiện tại và điều chỉnh theo múi giờ.
  • generateGreetings: Tạo lời chào dựa trên thời gian trong ngày.
  • getQuotes: Lấy câu trích dẫn từ API ZenQuotes.
  • generateFile: Tạo file README.md với nội dung được cập nhật.

Bước 4: Cài đặt và chạy workflow

Cài đặt các dependencies cho dự án Node.js:

npm init -y
npm install axios markdown-it

Bây giờ, workflow của bạn đã sẵn sàng để chạy theo schedule đã setup hoặc chạy thủ công từ trang GitHub Actions của bạn.

Đọc những bài viết khác của tác giả: Chillwithsu.com

Donate cho tác giả : Buy me a coffee

Chúc các bạn code vui, khỏe, giải trí !!!



All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí