Node.jsのパッケージsimple-gitを使ってgitコマンドを呼び出す。なぜか2回目のpushでやっと全ファイルがアップされることを発見した。原因不明。

ブツ

インストール&実行

NAME='Electron.simple.git.20220902105438'
git clone https://github.com/ytyaru/$NAME
cd $NAME
npm install
npm start

準備

  1. GitHubアカウントを作成する
  2. repoスコープ権限をもったアクセストークンを作成する
  3. インストール&実行してアプリ終了する
    1. db/setting.jsonファイルが自動作成される
  4. db/setting.jsonに以下をセットしファイル保存する
    1. username:任意のGitHubユーザ名
    2. email:任意のGitHubメールアドレス
    3. token:repoスコープ権限を持ったトークン
    4. repo:任意リポジトリ名(mytestrepo等)
    5. address:任意モナコイン用アドレス(MEHCqJbgiNERCH3bRAtNSSD9uxPViEX1nu等)
  5. dst/mytestrepo/.gitが存在しないことを確認する(あればdstごと削除する)
  6. GitHub上に同名リモートリポジトリが存在しないことを確認する(あれば削除する)

実行

  1. npm startで起動またはアプリでCtrl+Shift+Rキーを押す(リロードする)
  2. git initコマンドが実行される
    • repo/リポジトリ名ディレクトリが作成され、その配下に.gitディレクトリが作成される
  3. [createRepo][]実行後、リモートリポジトリが作成される
    • なぜかasset/ディレクトリとその配下のファイル一式がアップロードされない……
    • ローカルリポジトリのほうにはちゃんと存在する

リモートリポジトリをみると、なぜか投げモナコイン用画像があるasset/ディレクトリがアップロードされない。

色々試しているうちに、なぜかもう一度git pushするとアップロードされることを発見した。そこでアプリ起動時にいつもgit pushするよう実装した。ようするに2回目の起動でasset/ディレクトリがアップされる。

初回のgit pushasset/がアップされない原因は不明。一回にpushできるファイル数には限りがあるなど、隠れた制約があるのかな?

  1. アプリでCtrl+Shift+Rキーを押す(リロードする)
    • もう一度git pushされる
  2. asset/ディレクトリとその配下のファイル一式がアップロードされる

GitHub Pages デプロイ

アップロードされたファイルからサイトを作成する。

  1. アップロードしたユーザのリポジトリページにアクセスする(https://github.com/ユーザ名/リポジトリ名
  2. 設定ページにアクセスする(https://github.com/ユーザ名/リポジトリ名/settings
  3. Pagesページにアクセスする(https://github.com/ユーザ名/リポジトリ名/settings/pages
    1. SourceのコンボボックスがDeploy from a branchになっていることを確認する
    2. Branchmasterにし、ディレクトリを/(root)にし、Saveボタンを押す
    3. F5キーでリロードし、そのページにhttps://ytyaru.github.io/リポジトリ名/のリンクが表示されるまでくりかえす(数分かかる
    4. https://ytyaru.github.io/リポジトリ名/のリンクを参照する(デプロイ完了してないと404エラー)

すべて完了したリポジトリとそのサイトが以下。

バグ発見

作成リポジトリをみると画像ファイルはアップされているのに、作成DEMOでは投げモナボタン画像が表示されない。なぜ?

開発者ツールのコンソールをみると画像ファイルが404エラーになってた。どうやらパスを間違えているようだ。ソースコード上では以下のようになっており、それが404エラーになっている。

ただしくはsrcを省いた以下URL。これをブラウザのURLに入力すれば表示される。つまりgit pushにより画像ファイルのアップ自体は成功している。

パスのバグを直したいけど、それよりもgitのほうが先。なぜ2回pushが必要なのか。どう対処すべきか。

経緯

Electronでgit pushできたが、なぜか一部アップされなかったとき、なぜか一部ファイル、モナコイン用画像ファイルがpushされなかった。原因不明。別の方法でpushできないかと思いググってみたところsimple-gitを見つけたので、今回試してみることにした。

ただしsimple-gitはシステムにインストールされたgitコマンドをNode.jsの標準APIchild_process.spawn()で実行するラッパーらしい。それは私が実装している以下のコードと大差ないのでは? とも思う。けれど他に対案もないので藁にもすがる思いで試すことにした。

const util = require('util')
const childProcess = require('child_process');
ipcMain.handle('shell', async(event, command) => {
    const exec = util.promisify(childProcess.exec);
    return await exec(command);
    //let result = await exec(command);
    //document.getElementById('result').value = result.stdout;
})

今回

結果的には同じだったが、色々試しているうち、なぜか2回目のpushで前回アップされなかったファイルがアップされることを発見した。なにこれ、どゆこと?

コード抜粋

main.js

const simpleGit = require('simple-git');

ipcMain.handle('gitInit', async(event, username, token, dirPath, repo, remote)=>{// remote='origin'
    console.log(`----- gitInit -----`)
    const git = simpleGit(`${dirPath}/${repo}`);
    git.clean(simpleGit.CleanOptions.FORCE)
    await git.init()
    await git.addRemote(remote, `https://${username}:${token}@github.com/${username}/${repo}.git`)
})
ipcMain.handle('gitPush', async(event, username, email, dirPath, repo, remote, branch, message)=>{
    console.log(`----- gitPush -----`)
    simpleGit(`${dirPath}/${repo}`)
        .addConfig('user.name', username)
        .addConfig('user.email', email)
        //.add('./*') // assetディレクトリ自体アップされず
        //.add('**/*') // asset/blank.mdファイルを追加するとそれだけアップされた
        .add('.') // assetディレクトリ自体アップされず(二回目のpushでアップされることを発見)
        .commit(message)
        .push(remote, branch);// remote='origin', branch='master'
})

全ファイルをアップロードするとき、git.add()の引数を少し変えてみたりした。コマンドだとgit add .がそれに該当するので、同じようにしてみた。simple-git READMEでは./*のような引数しか書いてなかった。

preload.js

    gitInit:async(username, token, dirPath, repo, remote)=>await ipcRenderer.invoke('gitInit', username, token, dirPath, repo, remote),
    gitPush:async(username, email, dirPath, repo, remote, branch, message)=>await ipcRenderer.invoke('gitPush', username, email, dirPath, repo, remote, branch, message),

renderer.js

const exists = await git.init(document.getElementById('github-repo').value)
if (!exists) { // .gitがないなら
    const res = await hub.createRepo({
        'name': `${setting.github.repo}`,
        'description': 'リポジトリの説明',
    }, setting)
    await maker.make()
    await git.push('新規作成')
} else {
    await git.push()
}

git.js

class Git {
    async init() {
        const exists = await window.myApi.exists(`${this.dir}/${this.repo}/.git`)
        if(!exists) {
            await window.myApi.mkdir(`${this.dir}/${this.repo}`)
            let res = await window.myApi.gitInit(this.username, this.token, this.dir, this.repo, this.remote)
        } else {
            console.log(`${this.dir}/${this.repo}/.git は既存のためgit initしません。`)
        }
        return exists
    }
    async push(message=null) {
        if (!message) { message = `追記:${new Date().toISOString()}` }
        let res = await window.myApi.gitPush(this.username, this.email, this.dir, this.repo, this.remote, this.branch, message)
    }