Closed12

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

kyoh86kyoh86

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

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

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

kyoh86kyoh86

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で自動公開してしまうとか。

kyoh86kyoh86

一応こういうスクリプトを作れば、「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)
kyoh86kyoh86

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

 ---
-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的に大丈夫なのかなコレ

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

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

kyoh86kyoh86

inputsにほしそうなもの

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