ハトネコエ Web がくしゅうちょう

プログラミングやサーバー・Web制作、チームマネジメントなど得た技術のまとめ

起動すぐに『Windows Media Playerは動作を停止しました』となる問題の解決

Windows Media Player が再生を初めて数秒で
Windows Media Playerは動作を停止しました』と出て終了する問題に、この数週間悩まされてきました。

別の再生プレイヤー使おうか……
いや、でもWindows Media Playerは動作が軽いし広告出ないからいいんだよなぁ……。

iTunes は再生すると必ずライブラリに登録されるから自作曲を再生させたくないし、
Groove Player(Windows10からのプレイヤー)はファイルをダブルクリックしてもたまに再生始めないことがあるし……。

「プログラムと機能」の「Windowsの機能の有効化または無効化」で一度無効にして再起動して有効にすれば直るよー、ってのを試しても解決しなかったので、
「もうダメじゃー」とあきらめていたのですが、今日調べなおしたら、Yahoo知恵袋で1つの答えを見つけて、それを試したら直りました。

Windows10 だからこの解決法は無関係かなーと思っていたので、予想外に直って感動しました。

それは、 https://support.microsoft.com/ja-jp/kb/2970908 にあるMicrosoft 簡易修正ツールソリューション」の中の、

の三項目を実行させるというものです。

なお、私はライブラリを開くとすぐに『Windows Media Playerは動作を停止しました』が出ていましたので、
2番目の『Windows Media Player のライブラリの問題を検索・修正する』の実行が効果を発揮したんだと思います。

このページ全然知りませんでしたが、他のことでもお世話になることがあるかもですね。
快適なWindows音楽ライフに戻れました! よかったよかったー

GitHub Pages にビルドしたフォルダだけを上げたいときの Circle.yml

GitHub に git push するだけでウェブサイトを作成・更新できる GitHub Pages 。便利です。
ちょっとめんどくさいのが、 gh-pages ブランチか master ブランチのトップディレクトリに index.html がないといけないところ。
( master ブランチの場合は docs と名付けたフォルダをトップディレクトリにすることも可能)

gulp とか webpack とかで最終的な出力を build フォルダに向けてしている……なんて場合は、この仕様がけっこう厄介です。
デプロイ先のフォルダ名を docs とするのは一つの解決方法ですが、最終出力先のフォルダ名としてどうなの? って気持ちになります。

そこで、GitHub ユーザーにとっての CIツールとしておなじみ、 CircleCI の出番です!
CircleCIgh-pages ブランチへの git push をお願いしちゃいましょう!

【追記(2019/5/24)】
この記事の内容は古いです。現在は CircleCI 2.0 ですので、以下の記事をご覧ください。

nekonenene.hatenablog.com

0. 前置きの雑談

さっきから出力とかビルドとかデプロイとか言葉が安定しませんが、全部同じ意味で使ってると思ってください。
Sass が CSS ファイルになったり webpack で JS が出力されるのとかをコンパイルって呼んで、minify 系は圧縮と呼んで、それら一連のことがおこなわれるのをビルドとかデプロイとか呼んでる感じです。

正確にはそういう一連のコンパイルの流れを「ビルド」と呼んで、
人がさわれる状態になる(今回CircleCIが担当する、GitHub Pages への公開・更新)のを「デプロイ」と呼び、
サービス開始を「リリース」と言うらしいです。

私はビルドのことデプロイって言ったり、デプロイのことリリースって言ったりするので、
「あ〜この人あたまがわるいんだ〜」と笑いながら読んでください。

ディレクトフォルダも同じ意味くらいの気持ちで使ってますけど気にしないでね!

1. circle.yml の設定

答えから見せたほうがわかりやすいと思うので、まず出来上がりを見せます。
細かい注意点はそのあとに書いていきます。

src ディレクトリの中にある .scss ファイルや .pug ファイルを、タスクランナー gulp によってビルドし、
build ディレクトリに出力している形です。

1-1. CircleCI を働かさない branch の指定

general:
  branches:
    ignore:
      - gh-pages

まずはこの部分で、 gh-pages ブランチへの push があっても CircleCI が走らないよう設定されています。
今回は gh-pages ブランチに直接 push する予定はないので、この設定(もしくは以下に述べる [ci skip] の設定のいずれか)は本当はいりません。

f:id:nekonenene:20161102022958p:plain

上の写真のように、CI の実行がスキップされたログは残ります。
すこし邪魔ですが、ログがないと CircleCI の挙動がおかしいのか SKIPPED されたかわかりませんから必要ですね。

1-2. npm パッケージのインストール

dependencies:
  pre:
    - rm -rf node_modules
  override:
    - npm install

まず node_modules フォルダを削除しています。
CircleCI はキャッシュを持つのですが、 node_modules ディレクトリ内のキャッシュが悪さして変なところで CI が止まるということはよくあって、
しばらく原因解明に悩む時間がたびたび発生するので潔く削除しています。
(CircleCI には「Rebuild without cache」というボタンもあるのですが、そもそもキャッシュが原因の可能性を見落としがち)

1-3. ビルド

deployment:
  deploy:
    branch: master
    commands:
      - npm run build

branch: master と指定することで、 master ブランチへの push による CircleCI タスクのときのみ、この deploy 部分は働きます。
他のブランチへの push でも gh-pages に反映させたいという場合は、この記述は無くすといいでしょう。

その後に、 npm run build でビルドします。
以下のように package.json に書かれているために、npm run build とコマンドすると gulp build がおこなわれます。

# package.json より一部抜粋
  "scripts": {
    "build": "gulp build"
  }

gulp build の中身は gulpfile.js に記述しています。
大ざっぱに言うと、src ディレクトリにあるファイルをビルドして build ディレクトリに出力する処理が書かれています。

1-4. build ディレクトリの中身をトップディレクトリに

    commands:
      - npm run build
      - rm -rf src
      - cp -Rf build/. ./

ビルドし終わったら src フォルダは用済みなので消しています。
特に深い意味はありません。なんとなく消しています。

大事なのは cp -Rf build/. ./ の方です。
build フォルダの中身をトップディレクトリにコピーしてきます。

R オプションでフォルダの下を潜ってファイルを探します。
f オプションで、コピー先に同名のファイルがたとえあっても容赦なく上書きします。

個人的にハマったのは、build でも build/ でもなく、build/. が正解なことです。そっかー。

.gitignore によって build ディレクトリを含めてないから考えていませんでしたが、
ここ cp コマンドでなく mv コマンドでもよさそうですね。

1-5. git push で gh-pages へデプロイ

  - git config --global user.name  "CircleCI"
  - git config --global user.email "circleci@gh-pages.com"
  - git add .
  - git commit -m "Publish [ci skip]"
  - git checkout -B gh-pages
  - git push -u origin gh-pages --force

さて、ビルドが終わりました。
あとはデプロイ! git push までの流れを見ましょう。

1-5-1. git config

まずは git config で username と email の設定を入れます。
値はなんでもいいですが、この設定をしておかないとコミット git commit ができません。

1-5-2. git commit

コミットメッセージが「Publish [ci skip]」となっていますね。
この [ci skip] の部分が特別で、コミットメッセージにこの文字が含まれているコミットに対して、CircleCI は処理をおこないません。

通常は 1-1. で書いた特定のブランチを無視する方法だけでいいと思いますが、
おもしろい仕組みだなと思いましたので書いておきました。

1-5-3. add branch & checkout

続いて git checkout -B gh-pages です。

新しいブランチを作りつつチェックアウトする b オプションは知っていたのですが、
すでに同名のブランチがある場合はエラーを発生させてしまうオプションなので「どうしよう」と悩んでいたのですが、
この B オプションならば、基本は b オプションと同様ながら「すでに同名のブランチがある場合はブランチの作成をせずチェックアウトする」ようです。助かりました。

1-5-4. git push

そして最後に gh-pages ブランチをリモートリポジトリに git push します。
pull を要求されてはエラーになりますので、force オプションを付けます

2. git push だ! の前に……

CircleCI が git push できるようにするためには下準備が必要です。

CircleCI のプロジェクトページ(対象リポジトリ)に飛び、PROJECT SETTINGS を開き、
PERMISSIONS の「Checkout SSH keys」をクリックします。

f:id:nekonenene:20161102031951p:plain

すでに deploy key はあるかと思いますが、これには git pull の方の権限しかありませんので、user key を作成します。

Add user key のところにある「Authorize with GitHub」ボタンをクリックして user key を発行してください。
それが終わりますと下準備は完了です。

あとは push し無事にビルドが終了すれば、

https://YOUR_USENAME.github.io/REPOSITORY_NAME  

にページが作成されます。

3. Failed にならないために

test:
  override:
    - npm run test

CircleCI には test の部分があります。
ここを省略することは可能ですが、書かないと、必ず結果が Failed になってしまいます。

精神的に Failed ラベルが並ぶのは嫌ですし、
すべてが Failed となってしまうのでは、ビルドに失敗しての Failed などと見分けがつきません。

とはいえ、作りたてのプロジェクトなど、
テストコードがない場合もあるかと思います。

その場合は、test の部分は cd ./echo 'にんじんたべたい' などと、
当たり障りのないコマンドを書いておくといいかと思います。

4. 余談 : yarn

公開した circle.yml では npm install としていますが、実際は

dependencies:
  pre:
    - rm -rf node_modules
    - npm install -g yarn
  override:
    - yarn install

test:
  override:
    - yarn test

deployment:
  deploy:
    branch: master
    commands:
      - yarn build

のように、npm から yarn に乗り換えつつあります。
rm -rf node_modules のあとに yarn cache clear を書いたほうが安全かも)

今のところは特に問題が起きていません。
……が、yarn をインストールさせることなく npm だけで終わらせたほうが CircleCI のタスクにかける時間が 1分近く少なくて、複雑な気持ちになっています。
yarn.lock による安定さが優れてるのではって勝手に期待してるんだけど、どうでしょう?

gibo はときどき update しようなって話

便利ツール gibo

.gitignore を生成するのってめんどくさい、なんのファイル書けばいいねん。
ってなる悩みを解消してくれた gibo 。( https://github.com/simonwhitaker/gibo )

gibo OSX Windows Node >> .gitignore

# .gitignore がすでにある場合は >>
# 新規作成なら >> のとこは >

こんなコマンドで必要な .gitignore をバーっと書き込んでくれます。親切。

2015年12月から更新されてないですが、まあ単純な仕組みなのでいいのかな。

仕組みはシンプルで、
https://github.com/github/gitignore
リポジトリをユーザーディレクトリ直下に .gitignore-boilerplates というフォルダを作り clone してきて、
必要に応じてその中身のテキストを貼り付ける、という仕組みです。

というわけで大事なのが、 .gitignore-boilerplates の中身!

gibo のアップデート、ちゃんとしてますか?

gibo が最新版だから大丈夫、ではないのです。
大事なのは.gitignore-boilerplates の中身

これを更新してあげないことには .gitignore の中身が少しずつ現在のアプリに則さない、使えないものになってしまいます。

ってことで以下のコマンドです。

gibo -u

単純!

gibo -u を実行すると、以下のようなログが流れました。

Updating a55134f..0f88fa7
Fast-forward
 .github/PULL_REQUEST_TEMPLATE.md          |  11 +++++++
 Actionscript.gitignore                    |   8 +++++
 Android.gitignore                         |  15 ++++++++--
 Autotools.gitignore                       |   4 +++
 C++.gitignore                             |   4 +++
 C.gitignore                               |  19 ++++++++++++
 CMake.gitignore                           |   1 +
 CakePHP.gitignore                         |  14 ++++++++-
 Composer.gitignore                        |   2 +-
 Concrete5.gitignore                       |   1 +
 D.gitignore                               |   4 +++
 Delphi.gitignore                          |   9 ++++++
 Drupal.gitignore                          |   2 +-
 Eagle.gitignore                           |   8 +++++
 Elm.gitignore                             |   3 +-
 Erlang.gitignore                          |   2 +-
 ExtJs.gitignore                           |   8 +++++
 FuelPHP.gitignore                         |  23 ++++++++++++--
 Global/Ansible.gitignore                  |   1 +
 Global/Bazaar.gitignore                   |   2 ++
 Global/CVS.gitignore                      |   2 +-
 Global/Calabash.gitignore                 |  10 +++++++
 Global/Dreamweaver.gitignore              |   4 +++
 Global/Dropbox.gitignore                  |   4 +++
 Global/Eclipse.gitignore                  |  20 ++++++++++---
 Global/EiffelStudio.gitignore             |   2 +-
 Global/Emacs.gitignore                    |  10 +++++++
 Global/JetBrains.gitignore                |  31 ++++++++-----------
 Global/Linux.gitignore                    |   6 ++++
 Global/Matlab.gitignore                   |   3 ++
 Global/MicrosoftOffice.gitignore          |   3 ++
 Global/NetBeans.gitignore                 |   2 --
 Global/SublimeText.gitignore              |  13 ++++++++
 Global/Tags.gitignore                     |   1 +
 Global/Vim.gitignore                      |   6 +++-
 Global/VirtualEnv.gitignore               |   2 ++
 Global/VisualStudioCode.gitignore         |   6 ++--
 Global/Xcode.gitignore                    |   8 ++---
 Global/XilinxISE.gitignore                |  10 +++++++
 Global/{OSX.gitignore => macOS.gitignore} |  50 ++++++++++++++++---------------
 Go.gitignore                              |   6 ++++
 Gradle.gitignore                          |   5 +++-
 Haskell.gitignore                         |   4 +++
 Joomla.gitignore                          |  37 +++++++++++++++++++++++
 Julia.gitignore                           |   4 +++
 KiCAD.gitignore => KiCad.gitignore        |   9 +++++-
 LICENSE                                   | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
 Laravel.gitignore                         |   6 ++--
 Leiningen.gitignore                       |   3 +-
 Magento.gitignore                         |  40 ++++++-------------------
 Nanoc.gitignore                           |   4 +--
 Node.gitignore                            |  20 +++++++++++--
 Objective-C.gitignore                     |  19 +++++++++---
 OpenCart.gitignore                        |   9 ++++++
 PlayFramework.gitignore                   |   1 -
 Prestashop.gitignore                      |   9 +++++-
 Python.gitignore                          |  31 +++++++++++++++++++
 Qt.gitignore                              |   8 +++--
 R.gitignore                               |  14 +++++++++
 README.md                                 |   2 +-
 Rails.gitignore                           |  17 ++++++++---
 Ruby.gitignore                            |  16 +++++++++-
 Rust.gitignore                            |  17 +++++------
 Scala.gitignore                           |   4 +++
 Scheme.gitignore                          |   7 +++++
 Smalltalk.gitignore                       |  18 +++++++++++
 SugarCRM.gitignore                        |   2 ++
 Swift.gitignore                           |  24 +++++++++++----
 Symfony.gitignore                         |  13 +++++++-
 TeX.gitignore                             |  68 ++++++++++++++++++++++++++++++++++++++----
 Terraform.gitignore                       |   6 ++++
 Typo3.gitignore                           |   2 +-
 Umbraco.gitignore                         |   8 +++--
 Unity.gitignore                           |  12 +++++++-
 UnrealEngine.gitignore                    |   7 +++--
 VisualStudio.gitignore                    |  58 +++++++++++++++++++++++++++++++-----
 WordPress.gitignore                       |   8 ++---
 ZendFramework.gitignore                   |   5 ++++
 78 files changed, 812 insertions(+), 180 deletions(-)
 create mode 100644 .github/PULL_REQUEST_TEMPLATE.md
 create mode 100644 Global/Ansible.gitignore
 create mode 100644 Global/Bazaar.gitignore
 create mode 100644 Global/Calabash.gitignore
 create mode 100644 Global/Dropbox.gitignore
 rename Global/{OSX.gitignore => macOS.gitignore} (81%)
 create mode 100644 Julia.gitignore
 rename KiCAD.gitignore => KiCad.gitignore (56%)
 create mode 100644 Scheme.gitignore
 create mode 100644 Smalltalk.gitignore
 create mode 100644 Terraform.gitignore

死ぬほど変わってた・・・。

a55134f のリビジョンっていつなのかと見たら 2015/10/30 でした。
つまり私が gibo を使って一周年ということですね?!

あと注目すべきは

rename Global/{OSX.gitignore => macOS.gitignore}

の行です。

冒頭で書いたコマンドは今後は

gibo macOS Windows Node >> .gitignore

と書かなければいけません。ちょっとタイプ量が増えますが、macOSって名前にもなじんできたのですぐに慣れるはず。

以上、 gibo -u 大事だよ!
って話でした。「gibo OSX」と打ち込んでいる人を見かけたら、口汚く罵ってあげてください。