Objavljeno

Korištenje GitHub Actions za kreiranje obavijesti o objavljivanju blog posta

Autori

Kako sam kreirao podsjetnik da napišem blog post koristeći GitHub Actions

Kao pisac, shvatam važnost dosljednosti kada je u pitanju objavljivanje novog sadržaja. Međutim, ponekad život stane na put, i može biti teško sjetiti se da napišem novi blog post. Kako bih ostao u toku sa svojim rasporedom dijeljenja, kreirao sam jednostavan podsjetnik koristeći GitHub Actions. U ovom postu ću podijeliti kako sam napravio ovaj radni proces.

Šta je GitHub Action?

GitHub Actions je moćan alat koji vam omogućava automatizaciju vaših radnih procesa. Možete ga koristiti za izgradnju, testiranje i implementaciju vašeg koda. Također ga možete koristiti za izvođenje širokog spektra drugih zadataka, kao što su slanje obavijesti ili planiranje podsjetnika.

Kako sam kreirao podsjetnik da napišem blog post

Da bih kreirao podsjetnik da napišem blog post, koristim poseban repozitorij na GitHubu README.md i dodao sam datoteku pod nazivom .github/workflows/blog-posts.yml. U ovoj datoteci sam definirao radni proces koji će GitHub Actions izvršiti. Evo početnog sadržaja datoteke:

name: Blog Posts

on:
  schedule:
    - cron: '0 0 * * 0' # Pokreni u 00:00 svaku nedjelju
  workflow_dispatch:

jobs:
  update-posts:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Ažuriranje liste postova
        run: |
          sleep 1m
          curl -LO https://blog.imam.dev/feed.xml
          node src/list-posts.js
          rm feed.xml
      - name: Commit promjene
        run: |
          git config --local user.email "github-actions[bot]@users.noreply.github.com"
          git config --local user.name "github-actions[bot]"
          git add -A
          git diff-index --quiet HEAD || git commit -m "Ažuriranje blog postova"
      - name: Pull promjene
        run: git pull -r
      - name: Push promjene
        uses: ad-m/github-push-action@0fafdd62b84042d49ec0cb92d9cac7f7ce4ec79e
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}

Ovaj radni proces se pokreće svaku nedjelju u 00:00 sati. Zatim pokreće skriptu koja ažurira listu blog postova. Skripta je napisana u JavaScript-u i parsira RSS feed mog bloga. Zatim generira listu blog postova i ažurira datoteku README.md. Na kraju, izvrši commit promjena i potisne ih na GitHub. Koristim ouuan-ov repozitorij kao referencu za ovaj radni proces.

Odakle dolazi podsjetnik? Zapravo je u datoteci list-posts.js. Dodao sam podsjetnik na listu blog postova. Evo sadržaja datoteke:

const { readFileSync, writeFileSync } = require('fs')

/**
 * Pretvori XML string u JSON
 * @param {string} xmlString
 * @returns {object} json
 */
const xmlToJson = (xmlString) => {
  const regex = /<(\w+)([^>]*)>([\s\S]*?)<\/\1>/gm
  const matches = xmlString.matchAll(regex)
  const json = {}

  for (const match of matches) {
    const [, key, attributes, value] = match
    const subMatches = value.matchAll(regex)
    const subJson = {}

    for (const subMatch of subMatches) {
      const [, subKey, subAttributes, subValue] = subMatch

      if (subValue.match(regex)) {
        if (Array.isArray(subJson[subKey])) {
          subJson[subKey].push(
            xmlToJson(`<${subKey}${subAttributes}>${subValue}</${subKey}>`)[subKey]
          )
        } else if (subJson[subKey]) {
          subJson[subKey] = [
            subJson[subKey],
            xmlToJson(`<${subKey}${subAttributes}>${subValue}</${subKey}>`)[subKey],
          ]
        } else {
          subJson[subKey] = xmlToJson(`<${subKey}${subAttributes}>${subValue}</${subKey}>`)[subKey]
        }
      } else if (Array.isArray(subJson[subKey])) {
        subJson[subKey].push(subValue)
      } else if (subJson[subKey]) {
        subJson[subKey] = [subJson[subKey], subValue]
      } else {
        subJson[subKey] = subValue
      }
    }

    if (json[key]) {
      if (Array.isArray(json[key])) {
        json[key].push(subJson)
      } else {
        json[key] = [json[key], subJson]
      }
    } else {
      json[key] = subJson
    }
  }

  return json
}

/**
 * Sortiraj JSON po pubDate
 * @param {object} json
 * @returns {object} sortedJson
 */
const sortJson = (json) => {
  json.sort((a, b) => new Date(b.pubDate) - new Date(a.pubDate))
  return json
}

// Pročitaj XML datoteku i pretvori u JSON
const xmlString = readFileSync('feed.xml', 'utf8')
const feeds = sortJson(xmlToJson(xmlString).rss.channel.item)

// Kreiraj Markdown listu postova
const posts = feeds
  .slice(0, 5)
  .map(
    (item) =>
      `- ${new Date(item.pubDate).toISOString().split('T')[0]} [${item.title}](${
        item.link
      }?utm_source=GitHubProfile)`
  )

// Ažuriraj README.md ako su se postovi promijenili,
// inače baci grešku da me podsjeti da napišem blog post
const readme = readFileSync('README.md', 'utf8')
if (readme.includes(posts.join('\n'))) {
  throw new Error('Nema novih blog postova')
} else {
  const updatedReadme = readFileSync('README.md', 'utf8').replace(
    /(?<=<!--START_SECTION:blog-posts-->\n)[\s\S]*(?=\n<!--END_SECTION:blog-posts-->)/,
    posts.join('\n')
  )
  writeFileSync('README.md', updatedReadme)

  console.log('Ažurirana datoteka README.md')
}

Skripta čita RSS feed mog bloga i generira listu blog postova. Zatim ažurira datoteku README.md sa listom blog postova. Ako nema novih blog postova, baci grešku da me podsjeti da napišem blog post.

To je samo greška koja će se baciti kada se skripta izvrši dok su postovi isti, a ne podsjetnik koji će se poslati na moju e-poštu ili nešto vidljivije za mene. Stoga sam odlučio omogućiti obavijest za sve neuspješne pokretanje radnog procesa. Evo kako to učiniti:

  1. Kliknite na gornji desni ugao stranice i odaberite Postavke.

  2. Odaberite Obavijesti na lijevoj bočnoj traci.

  3. Kliknite na Akcije.

  4. Odaberite Pošalji obavijesti samo za neuspješne radne procese.

Sada ću dobiti obavijest kada se skripta izvrši, a nema novih blog postova. Također mogu vidjeti obavijest na web stranici GitHub-a.

Još jedan način koji sam istraživao

Prethodni radni proces o kojem vam pričam je modificirana verzija tako da je moj README.md uvijek ažuran. Također sam istraživao i drugi način da kreirao podsjetnik da napišem blog post. Ali, to je samo podsjetnik bez mehanizma ažuriranja README.md, samo podsjetnik.

Da bih kreirao podsjetnik da napišem blog post, kreirao sam novi repozitorij na GitHubu i dodao datoteku pod nazivom .github/workflows/remind.yml. U ovoj datoteci sam definirao radni proces koji će GitHub Actions izvršiti. Evo sadržaja datoteke:

name: Podsjetnik da napišem blog post

on:
  schedule:
    - cron: '0 10 * * 1-5'

jobs:
  remind:
    runs-on: ubuntu-latest
    steps:
      - name: Pošalji podsjetnik
        uses: dawidd6/action-send-mail@v3.1.0
        with:
          server_address: smtp.gmail.com
          server_port: 465
          username: ${{ secrets.EMAIL_USERNAME }}
          password: ${{ secrets.EMAIL_PASSWORD }}
          subject: 'Podsjetnik da napišete novi blog post'
          body: "Ne zaboravite da danas napišete novi blog post!"
          to: my-email@example.com

Ovaj radni proces mi šalje e-poštu podsjetnik svakog radnog dana u 10:00 sati, podsjećajući me da napišem novi blog post. Koristio sam akciju treće strane, dawidd6/action-send-mail, da bih poslao e-poštu. Dao sam svoje e-poštne podatke kao GitHub tajne, tako da nisu vidljive u datoteci radnog procesa.

Zaključak

Istraživao sam dva načina da kreirao podsjetnik da napišem blog post. Prvi način je ažuriranje datoteke README.md mog GitHub profila. Drugi način je slanje e-pošte podsjetnika. Trenutno koristim prvi način jer je vidljiviji od drugog načina. Može vidjeti podsjetnik svaki put kada posjetim svoj GitHub profil.

Kreiranje podsjetnika da napišem blog post koristeći GitHub Actions je jednostavan i efikasan način da ostanem u toku sa svojim rasporedom pisanja blogova. Sa ovim radnim procesom na mjestu, vi nikada nećete zaboraviti da napišete novi post. Ako ste zainteresirani za kreiranje vlastitog podsjetnika za radni proces, obavezno pogledajte dokumentaciju GitHub Actions da biste saznali više. Sretno bloganje!