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
準備
- GitHubアカウントを作成する
repo
スコープ権限をもったアクセストークンを作成する- インストール&実行してアプリ終了する
db/setting.json
ファイルが自動作成される
db/setting.json
に以下をセットしファイル保存するusername
:任意のGitHubユーザ名email
:任意のGitHubメールアドレスtoken
:repo
スコープ権限を持ったトークンrepo
:任意リポジトリ名(mytestrepo
等)address
:任意モナコイン用アドレス(MEHCqJbgiNERCH3bRAtNSSD9uxPViEX1nu
等)
dst/mytestrepo/.git
が存在しないことを確認する(あればdst
ごと削除する)- GitHub上に同名リモートリポジトリが存在しないことを確認する(あれば削除する)
実行
npm start
で起動またはアプリでCtrl+Shift+Rキーを押す(リロードする)git init
コマンドが実行されるrepo/リポジトリ名
ディレクトリが作成され、その配下に.git
ディレクトリが作成される
- [createRepo][]実行後、リモートリポジトリが作成される
- なぜか
asset/
ディレクトリとその配下のファイル一式がアップロードされない…… - ローカルリポジトリのほうにはちゃんと存在する
- なぜか
リモートリポジトリをみると、なぜか投げモナコイン用画像があるasset/
ディレクトリがアップロードされない。
色々試しているうちに、なぜかもう一度git push
するとアップロードされることを発見した。そこでアプリ起動時にいつもgit push
するよう実装した。ようするに2回目の起動でasset/
ディレクトリがアップされる。
初回のgit push
でasset/
がアップされない原因は不明。一回にpush
できるファイル数には限りがあるなど、隠れた制約があるのかな?
- アプリでCtrl+Shift+Rキーを押す(リロードする)
- もう一度
git push
される
- もう一度
asset/
ディレクトリとその配下のファイル一式がアップロードされる
GitHub Pages デプロイ
アップロードされたファイルからサイトを作成する。
- アップロードしたユーザのリポジトリページにアクセスする(
https://github.com/ユーザ名/リポジトリ名
) - 設定ページにアクセスする(
https://github.com/ユーザ名/リポジトリ名/settings
) Pages
ページにアクセスする(https://github.com/ユーザ名/リポジトリ名/settings/pages
)Source
のコンボボックスがDeploy from a branch
になっていることを確認するBranch
をmaster
にし、ディレクトリを/(root)
にし、Saveボタンを押す- F5キーでリロードし、そのページに
https://ytyaru.github.io/リポジトリ名/
のリンクが表示されるまでくりかえす(数分かかる) 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)
}