scrapbox-codesync
https://gyazo.com/cce54fbe28dca3ac94ce78665952ec52
Scrapbox上のコードをGithubリポジトリと同期して管理できるサーバレスアプリケーションです
ページを分けて汎用性を高めれば、他のプロジェクトから同じコードを呼び出して再利用できるので便利です
しかしながら、Scrapboxページはそのままではリポジトリによるコード管理ができません
ブラウザからScrapboxの該当ページへアクセスして、直接コードを書き換える必要があります
VSCode.iconVSCodeなど使い慣れたエディタやIDEが使えず、CSSやJavaScriptのバージョン管理もできません そこで、Github.iconGithubリポジトリのコードとScrapboxページを同期させる仕組みをつくりました Githubリポジトリを更新してプッシュすれば、自動的にScrapboxページが作成/変更されます
Scrapboxにはページ作成/更新APIが無いためブラウザ操作を自動化できるPuppeteer.iconPuppeteerを使い実現しています できること
GithubリポジトリでScrapboxのUserCSS/UserScriptをコード管理して同期します
GithubリポジトリからScrapboxへ一方向に同期します
ページ名のフォルダに入っているstyle.cssまたはscript.jsがScrapbox上に同期されます
code/css/ページ名/style.css
code/js/ページ名/script.js
フォルダ名すなわちページ名がScrapbox上で作成されるページ名です
コードの同期はGithubの指定ブランチのPushイベントをトリガーに行います
追加/修正があったコードがPUTの対象です
厳密には一度ページを削除してGithubリポジトリのコードでページを新規作成します
手動で全コードを同期させることもできます
できないこと
コードの削除には対応していません
Github上のコードを消してもScrapbox上の該当ページは消えません
ブラウザでScrapboxへアクセスして手で消してください
作成されるのはUserCSS/UserScriptが記載されたScrapboxページのみです
必要な箇所にimport文を自分で記載してください
Scrapboxページをブラウザで直接更新した場合、Githubリポジトリには反映されません
次のGithubリポジトリの更新で変更が上書きされるので注意してください
構成
Github.iconGithubのWebhook(Push)を受け取って起動 https://cacoo.com/diagrams/L5gAbKbq1avCXTpq-70E32.png
事前準備
該当プロジェクトフォルダに入るとNode.js v12 に自動的に切り替わる設定が入っています
まずNode.jsバージョン管理ツールのnvmを入れ、nvmでNode.js v12(lts/erbium)をインストールします
direnvをインストールして該当フォルダへアクセスするとv12へ自動的に切り替わります
事前にdirenv allow .を該当フォルダで実行して、direnvの対象としておきます
Serverless Frameworkはグローバルインストールしておきます
nvmで入れたNode.js v12でnpm i -g serverlessを実行します
一度そのままの状態でサーバレスフレームワークをデプロイさせてWebhook用のURLを取得します
sls deploy --stage prod
LambdaやAPI GatewayといったAWSリソースが作成されます
デプロイのためにAWSアカウントのprofile設定が必要です
serverless.ymlで指定されたprofile名に合わせて設定を行ってください
stageがprodならslsfw-prodがプロファイル名になります
code:serverless.yml
...
custom:
defaultRegion: ap-northeast-1
defaultStage: prod
profile: slsfw-${self:provider.stage} # Specify the profile according to the stage
environment:
...
GithubのWebhookにAPI Gatewayで発行されたURLを登録します
認証のためのオプション情報をデプロイ時に引き渡します
Webhookを受信する際にSignatureを検証します
GithubのWebhook登録時に設定したシークレットトークンをデプロイ時にオプションで指定します
sls deploy --stage prod --githubWebhookSecretToken xxxxx
コードはGithubリポジトリへAPIでアクセスして取得します
その際に、GithubのAPIトークンの指定も必要です
sls deploy --stage prod --githubApiToken ghp_xxxxx...xxx
Githubの管理画面から事前にPersonal access tokenを発行しておきます
事前にレポジトリへのアクセスを許可しておきます
プライベートポジトリの場合はレポジトリへのフルアクセス
repo(Full control of private repositories)
パブリックリリポジトリの場合はpublicの参照のみ
public_repo(Access public repositories)
Scrapboxへの書き込みは、該当プロジェクトに対して認証されている必要があります
ただし、Pupetterでは毎回ログイン処理を行いません
代わりにクッキーに認証済情報(connect.sid)を設定し、認証済状態でアクセスを行います
connect.sidは認証済のChromeブラウザから取得し、デプロイ時にオプションで指定します
sls deploy --stage prod --scrapboxConnectSid s%xxxxx...xxx
まとめると、デプロイ時に引き渡すオプションは以下となります
sls deploy --stage prod --githubWebhookSecretToken xxxxx --scrapboxConnectSid s%xxxxx...xxx --githubApiToken ghp_xxxxx...xxx
なお、トークンとクッキー情報は環境編集に設定しても読み込まれるようになっています
GITHUB_WEBHOOK_SECRET_TOKEN、GITHUB_API_TOKEN、SCRAPBOX_CONNECT_SID
オプションの設定が優先され、オプションが無い場合は環境変数を読みに行きます
ただし機密性の高い情報なので誤ってコミットしないようにご注意ください
原則、デプロイ時のオプションで設定することを推奨します
その他、以下の環境変数を指定してください
環境変数の設定ははルート直下にある.envにまとめています
Scrapboxのプロジェクト名
SCRAPBOX_PROJECT_NAMEにプロジェクト名を指定
例:https://scrapbox.io/waicode/のwaicodeの部分
作成ページのアイキャッチ画像
USER_CSS_EYECATCH_URLにUserCSSページで使う共通アイキャッチ画像をGyazo.iconGyazoのURLで指定 例:https://gyazo.com/bd9b8fac01f340c5dd9a4c6e75a38a0f
USER_SCRIPT_EYECATCH_URLにUserScriptページの共通アイキャッチ画像を同じくGyazoで指定
例:https://gyazo.com/6ca41a13b3ca4f0ea097dc5b27092762
作成ページにつけるタグ
USER_CSS_TAGにUserCSSページに付ける#から始まるタグを指定
例:#UserCSS
USER_SCRIPT_TAGにUserScriptページに付ける#から始まるタグを指定
例:#UserScript
同期処理の同時実行数
CONCURRENT_EXEC_NUMBERで指定(デフォルトは5)
一度に多くのコード同期を並列実行で実行すると、処理が重くなりタイムアウトします
Githubリポジトリオーナー
GITHUB_REPO_OWNER
リポジトリのオーナーを指定してください
例:https://github.com/waicode/scrapbox-codesyncのwaicodeの部分
Githubからコードを取得する際に利用します
Githubリポジトリ名
GITHUB_REPO_NAME
同様にリポジトリの名前を指定してください
例:https://github.com/waicode/scrapbox-codesyncのscrapbox-codesyncの部分
対象ブランチ
GITHUB_TARGET_BRUNCHで指定(デフォルトはmain)
指定したブランチ以外はプッシュを受け取っても同期処理を行いません
事前準備が完了したら再度デプロイを行います
sls deploy --stage prod --githubSecretToken xxxxx --scrapboxConnectSid s%xxxxx...xxx
使い方
以下の構成でUserCSSまたはUserScriptを作成します
UserCSS
code/css/ページ名/style.css
UserScript
code/js/ページ名/script.js
フォルダ名(ページ名)が作成するScrapboxのページ名となります
Githubのメインブランチ(main or master)をプッシュするとScrapboxへのコードが同期されます
他にも、以下コマンドでローカル環境から一括でScrapboxページを更新できます
sls invoke local --function allSync --scrapboxConnectSid s%xxxxx...xxx
注意事項
AWSリソースを作成するので、無料枠を超えて利用した場合に課金される点はご注意ください
頻繁に更新を行わない限り、無料枠におさまる範囲で利用できるとは思います
処理の簡素化と作成リソースを最小限に留めることを目的にAPI Gateway(webhook)から直接Lambdaを呼び出しています
API Gatewayで許容されるタイムアウトの最大値が30秒です
Lambdaのタイムアウト値は900秒に設定しているため、更新対象が多いとGithubへタイムアウトを返却します
Lambdaの処理自体は継続されます
時間のかかる処理なので、本来は同期処理は避けるべきです
たとえば間にSQS.iconSQSを挟み非同期で処理するのがベター LambdaでPupetterがタイムアウトしてしまう場合は、処理方式やスペックを個別に調整してください
環境変数の同時処理実行数CONCURRENT_EXEC_NUMBERを下げる
Lambdaのスペック(関数メモリなど)をserverless.ymlで指定する