Closed12

zenn.devに自動publishできたら便利そう

アドベントカレンダー的な使い方であれば、Branchで前もって運用するのも悪くないですね。

https://zenn.dev/j5c8k6m8/articles/zenn-adcal-github-action

GitHub Actionsのon:scheduleでやるってのはいい感じなんですけどね。
もうちょっと記事書くときに手軽に指定できたら良いなと思ったり

publish-on みたいなのFront Matterに指定したい。

---
title: "" # 記事のタイトル
emoji: "🐥" # アイキャッチとして使われる絵文字(1文字だけ)
type: "tech" # tech: 技術記事 / idea: アイデア記事
topics: [] # タグ。["markdown", "rust", "aws"]のように指定する
publish-on: 2020-12-01
published: false # 公開設定(falseにすると下書き)
---
npx zenn publish

とか、どうせpackage.json作るんだし

npm start publish

とかでも良いかも。
あとはGitHub Actionsで

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

みたいな走らせかたしてActionで自動公開してしまうとか。

一応こういうスクリプトを作れば、「publishAtに現在時刻より古い値が入った、published:falseな記事をpublished:trueに変える」みたいなことはできた

const path = require('path'),
      fs = require('fs').promises,
      frontmatter = require('@github-docs/frontmatter');

const schema = {
  properties: {
    title:     { type: 'string',  required: true },
    emoji:     { type: 'string',  required: true },
    type:      { type: 'string',  required: true, enum: ['tech', 'idea'] },
    topics:    { type: 'array',   required: true },
    published: { type: 'boolean', required: true },
    publishAt: { type: 'any' }
  }
};

async function publish_dir(dirpath) {
  const dir = await fs.opendir(dirpath);
  const now = new Date();
  for await (const dirent of dir) {
    const filepath = path.join(dirpath, dirent.name);
    if (!filepath.endsWith('.md')) {
      continue
    }

    const file = await fs.readFile(filepath, {'encoding': 'utf8'})
    const {data, content, errors} = frontmatter(file, {schema, filepath})
    if (errors.length > 0) {
      console.error(errors)
      continue
    }
    if (data.published) {
      console.debug('found published article: ' + dirent.name);
      continue
    }
    if (!('publishAt' in data)) {
      console.debug('found unreserved article: ' + dirent.name);
      continue
    }
    if (now.valueOf() <= new Date(data.publishAt).valueOf()) {
      console.debug('found unpublished article: ' + dirent.name);
    }
    console.info('publish ' + dirent.name);
    data.published = true;

    await fs.writeFile(filepath, frontmatter.stringify(content, data), 'utf8')
  }
}

const { program } = require('commander');

program
  .command('publish')
  .description('Make a "published" property in the articles which the "publishAt" is past')
  .action(async () => {
    await publish_dir('./articles');
  });

program.parseAsync(process.argv)

ただ、差分が余計に出る感じはある

 ---
-title: "Go製ツールをGitHub Container Registryに載せてGitHub Actionとして公開する" # 記事のタイトル
-emoji: "🐳" # アイキャッチとして使われる絵文字(1文字だけ)
-type: "tech" # tech: 技術記事 / idea: アイデア記事
-topics: ["docker", "github", "go", "githubactions"] # タグ。["markdown", "rust", "aws"]のように指定する
-publishAt: "2020-11-30"
-published: false # 公開設定(falseにすると下書き)
+title: Go製ツールをGitHub Container Registryに載せてGitHub Actionとして公開する
+emoji: "\U0001F433"
+type: tech
+topics:
+  - docker
+  - github
+  - go
+  - githubactions
+publishAt: '2020-11-30'
+published: true
 ---
  • YAMLコメントが消える
  • 絵文字がUnicodeエスケープされる
  • ダブルクォーテーションが消える
  • リストがYAML化される

Zenn的に大丈夫なのかなコレ

問題はない。

Timezoneの扱いが地味にアレだな。

index.js.diff
     }
     console.info('publish ' + dirent.name);
     data.published = true;
+    delete data.publishAt;
 
     await fs.writeFile(filepath, frontmatter.stringify(content, data), 'utf8')
   }

公開したらpublishAtは消さないと。

inputsにほしそうなもの

  • defaultTimezone
    • publishAt: "2020-11-20" みたいに書いたとき、これをどのTimezoneとして扱うか
    • zennターゲットならdefault: JSTでよさそう
  • dateKeyName
    • publishAt だと嫌だという場合に置き換えるやつ

dateKeyNameは面倒なので後回し。

このスクラップは2020/11/23にクローズされました
ログインするとコメントできます