sitateru tech blog: GitHub

sitateru tech blog

シタテルの技術やエンジニアの取り組みを紹介するテックブログです。

ラベル GitHub の投稿を表示しています。 すべての投稿を表示
ラベル GitHub の投稿を表示しています。 すべての投稿を表示

2021年12月22日水曜日

GitHub Container Registryに公開リポジトリを作ってみた

12月 22, 2021

みなさんはコンテナイメージはどこに置いているでしょうか。
シタテルでは「基本はECR、GCPで利用するイメージはGCR」というまあ普通な構成になっています。
ですがこの度、「せっかく作ったし公開しておいてもいいかな」というコンテナイメージの置き場としてGHCRを使い始めました。

GHCRとは

コンテナレジストリの利用 - GitHub Docs
GHCRはGitHub Container Registryの頭文字で、GitHub上でいろいろなパッケージを公開できるGitHub Packagesの一機能といったところでしょうか。
DockerfileをGitHubで管理するならGitHub上でイメージ配布まで完結するわけですね。

料金ですが、パブリックなパッケージについては無料となってます。今回のニーズにはちょうどいいですね。
About billing for GitHub Packages - GitHub Docs

イメージのpull/push等は ghcr.io/<OWNER>/<IMAGE_NAME>:<tag> という表記になります。(OWNERはGitHubのユーザー名やorganization名になります)

push前などに認証する場合は以下のようになります。

  1. write:packages スコープを持つアクセストークンを作っておく
  2. $ echo <token> | docker login ghcr.io -u USERNAME --password-stdin

リポジトリ作成・push

というわけで、organizationのPackagesにコンテナイメージをアップロードして公開してみましょう。
上記のコマンドで認証したら、好きなイメージ名とタグ名をつけてpushするだけです。

$ echo $GH_TOKEN | docker login ghcr.io -u sitateru --password-stdin
$ docker pull hello-world:latest
$ docker tag hello-world:latest ghcr.io/sitateru/hello-world:latest
$ docker push ghcr.io/sitateru/hello-world:latest

アップロードしたパッケージは、https://github.com/orgs/&lt;OWNER>/packagesのURLで一覧できます。


organizationにアップロードすると、最初はInternalというアクセス設定になるようです。

公開するためには、設定画面から Change package visiblity をクリックしてPublicを選択。
確認のためパッケージ名を入力してボタンをクリックすれば完了です。



リポジトリと紐づけ

作成したパッケージにはリポジトリを紐づけできるようになっています。
パッケージのページで Connect Repository をクリックしてリポジトリを選択すればOKです。


紐づけするとリポジトリのREADMEがパッケージのREADMEとして表示されるほか、パッケージのアクセス権限を「紐づけたリポジトリと等しくする」ことができます。管理の手間が楽になってありがたいですね。


どんなイメージを公開するか

現在のところ、ローカル開発環境やCIで使うために公式イメージに一手間加えたようなものばかりです。詳しくはリポジトリをご参照ください。

GitHub - sitateru/docker-images

ご利用はご自由にどうぞなのですが、保証やサポート等はできませんのでご了承ください🙇‍♂️
タグ追加などの要望があれば、issueなりPRなりいただければできる限り対応しますのでよろしくお願いします。

2021年1月15日金曜日

GitHub dependabot でDockerタグをバージョン指定する

1月 15, 2021

寒い日が続きますね。

ところで皆さんはGitHubのdependabotは使っていますでしょうか?
リポジトリをスキャンして、使っているライブラリやパッケージの脆弱性をお知らせしてくれるサービスですね。

依存関係を自動的に更新する - GitHub Docs

そのdependabotでちょっとした問題を調べて解決したので記録しておこうと思います。
題して「特定のDockerタグを無視する設定の書き方」です。
dependabotの概要や初期設定などはこの記事ではちょっと飛ばしますのでご了承ください🙇‍


dependabotはDockerタグにも対応していて、脆弱性対応された新しいバージョンタグがある場合はそれを出すようになっています。
例えばリポジトリの docker/Dockerfile をスキャン対象にする場合、コミットしておく設定ファイル .github/dependabot.yml はこのようになります。

version: 2
updates:
  - package-ecosystem: "docker"
    directory: "/docker"

さて、基本的にはdependabotはメジャーバージョンアップも含めて最新バージョンにアップデートさせるように動作するようです。
そのため、Dokerfileで node:14.x.x イメージを使っている場合

このように node:15 系にアップデートしなよ!というPRが作成されるのです。

でもNode.jsはバージョン14はLTSで15はLTSじゃない・・・更新するなら14系の最新にしてほしい!
というわけで、「Dockerタグの特定バージョンを無視する設定」を調べて入れてみました。


依存関係の更新の設定オプション - GitHub Docs

こちらのドキュメントによると、あるバージョンへの更新を無視するためにはdependabot.ymlにそのバージョンを明記すればいいのですが、

範囲を定義する場合は、パッケージマネージャーの標準パターンを使用します

Dockerタグの標準パターンって何だ・・・?🤔

結局わからなかったのでソースを見てみたところ、判定しているのはおそらくこのあたり。

dependabot-core/update_checker.rb at main · dependabot/dependabot-core · GitHub

バージョンの取り扱いに使っているのは Gem::Versionクラス のようです。

class Gem::Version (Ruby 3.0.0 リファレンスマニュアル)

ということはGemfileでバージョンを指定するのと同じ記法で良さそうですね。
dependabot.ymlはこうなりました。

version: 2
updates:
  - package-ecosystem: "docker"
    directory: "/docker"
    ignore:
      - dependency-name: "node"
        versions: ["~>15.0"]
        # nodeイメージの 15.x 系は無視

これでnodeイメージは 15.x を対象外にして更新するようになりました。
新しく作られるPRは14系の範囲でバージョンアップするものになっていますね。


dependabotでDocker更新、なかなか便利なのでお試しください🙏

2018年12月18日火曜日

FirebaseのSDKのプルリクを追ってみた

12月 18, 2018

こんにちは、シタテルの鶴巻です。 devops&インフラ担当です。

最近、firebase/firebase-admin-goの実装で気になったところがあり、プルリクエストから経緯を知ることができました。

GitHub上のソースコードで気になった箇所の経緯を追うことは今後もあると思うので、整理がてら方法を紹介します。

要約

  • firebase/firebase-admin-goの実装で気になったところがあった
  • git blameコマンドで、ソースコードが最後に編集されたhashを特定
  • 対象のソースコードが追加されたプルリクエストで経緯が分かった

firebase-admin-sdk-goの実装で気になった箇所

firebase-admin-sdk-goは、名前の通りFirebaseサービスをGolangから扱うためのSDKです。

Firebase Authenticationを試してみた際に、弊社で使用しているRubyのSDKがなかったため、GolangのSDKの実装を少し読んでみました。

そこで、Googleのサーバから公開鍵を取得するメソッドの中で排他制御が行われていることに着目しました。
私はここで排他制御を実施している理由がわからなかったので、経緯を調べることにしました。

該当ソースコードは以下です。
https://github.com/firebase/firebase-admin-go/blob/master/auth/token_verifier.go#L66-L76

func (k *httpKeySource) Keys(ctx context.Context) ([]*publicKey, error) {
    k.Mutex.Lock()
    defer k.Mutex.Unlock()
    if len(k.CachedKeys) == 0 || k.hasExpired() {
        err := k.refreshKeys(ctx)
        if err != nil && len(k.CachedKeys) == 0 {
            return nil, err
        }
    }
    return k.CachedKeys, nil
}

プルリクエストを見つける手順

1. git blameコマンドで、対象のソースコードが最後に編集されたcommitのHash値を特定

  • 対象のソースコードが最後に変更されたcommiのHash値はf3174984ということが特定できます
    $ git blame auth/token_verifier.go | grep -e "k.Mutex.Lock()" -e "defer k.Mutex.Unlock()"
    f3174984 auth/crypto.go         (Hiranya Jayathilaka 2017-05-18 13:45:30 -0700  67)     k.Mutex.Lock()
    f3174984 auth/crypto.go         (Hiranya Jayathilaka 2017-05-18 13:45:30 -0700  68)     defer k.Mutex.Unlock()

2. GitHubの対象レポのプルリクエストをHash値で検索

実装の理由は?

  • プルリクエストのコメントにありました

  • 複数のスレッドが共有している公開鍵のキャッシュを同時に更新するのを防ぐためにmutexを導入したみたいです。

Introduced a mutex to prevent multiple threads from updating the shared cache concurrently.

  • ソースコードを追うと、公開鍵取得のメソッドは httpKeySource構造体に定義されており、さらにhttpKeySourceはClient構造体に定義されています。SDKを使う際に最初にClientの初期化を行いますが、初期化した同一のClientで公開鍵取得メソッドがconcurrencyに実行されても安全なように実装されているのかなと考察しました。

firebase-admin-sdk-goはgit-flow

firebase-admin-sdk-goはgit-flowで開発されているようです。

そのため、masterのソースコードのcommitのHash値がプルリクエストがマージされた時のHash値と同じで、プルリクエストが見つけやすかったです。

おまけ(nodejsの実装)

Node.jsのSDKの同じ箇所の実装についても少し覗いてみました。

Node.jsを書いたことはありませんが、見る限り排他制御はしていないように見えます。

Node.jsはシングルスレッド推奨だから排他制御しなくていいのか・・・など思い、言語の特性の違いが垣間見えて面白いですね。

まとめ

  • オープンソース文化いいですね。今回の例だとfirebaseの中の人が書いたソースコードや、そのプルリクを見ることができています(もしかしたら中の人じゃないかもしれませんが)。エンジニアとしては当たり前な文化ですが、ブラックボックス化されている業界が多いなか改めて良い文化だと思いました。
  • シタテルはRailsを使用しているので、RubyのSDKがあればFirebase Auth導入してみたかったのですが残念です。

2018年11月16日金曜日

githubイシュー/PRの管理にjasperを導入したら幸せになった話

11月 16, 2018

こんにちは!

シタテルで エンジニアをしている建山です。

主に工場向けのマイオペというシステムの開発を行っています。

シタテルではgithubを使ってソースコード・イシュー/PR管理などをしています。
その中で、困るなとおもっていたのがイシューへのアサインやコメントに気づく仕組みでした。
PRやイシューで自分にアサインやコメントされているにもかかわらず、気づくかない、気づくのが遅くなるなど、あげくのはてに、slackでメンションもらったりということもありました。

そこで、リアルタイムに通知を受け取ったり、メンションにもれなく気づけるようになりたいとおもっていたところ、社内のエンジニアにjasperよさそう!とおしえていただいて実際便利でしたので紹介します。

jasper以外にもいい方法はいくつかあるとおもいますが、今回はjasperを使った方法を記載します。

jasperとは

githubのイシュー/PRを閲覧や管理をしやすくするソフトウェアです。
Mac版/Windows版/Linux版があります。
https://jasperapp.io/

cookpadのエンジニアの方がつくられているようです(https://techlife.cookpad.com/entry/2017/03/14/100000

ほとんどここに書かれています。

jasperを使った方法

jasperにはstreamsを登録する機能があります。こちらに登録しておくと、
条件ごとに一覧で見ることができて、通知を受け取りたい場合は、特定のstreamだけ通知を受け取るということもできます。

私が通知を設定しているstreamsはこちら。

公開中のイシューで自分にメンションもらっているリスト

is:issue is:open mentions:ユーザー名

公開中のイシューで自分に レビューリクエストもらっているリスト

is:open is:pr review-requested:ユーザー名

PRで自分にアサインもらっているリスト

is:open is:pr assignee:ユーザー名 archived:false

公開中のPRで自分にメンションもらっているリスト

is:pr is:open mentions:ユーザー名

まだ使いこなせていないのですが、ほかにもたくさんの用途にstreamを分けることができます。
https://jasperapp.io/doc.html#stream

個人的には、jasperを使いだして、github上でするべきコメントを、slack上でやることが減ったと感じています。github上にもコメントで経緯ものこるので、いいなと感じています。

日々、改善しながらやっていきたいと思います!

2018年11月6日火曜日

DXF TIIPビューワ

11月 06, 2018

こんにちは!
シタテル株式会社CTOの和泉です。

シタテルではユーザー様からの相談を相談をお受けして、衣服の生産管理を行っています。

その際、衣服のパターンデータをいただきますが、このパターンデータはDXFという形式のファイルで送られてきます。

正確にはDXFを拡張したアパレルCADデータ互換のTIIP規約としてフォーマットが規定されています。

アパレルCADデータ互換のTIIP規約

このファイルは通常、専用のソフトウェアを使って編集、閲覧するのですが、

「ブラウザ上でユーザー様とメッセージのやり取りをしている中でいちいちダウンロードして確認してというのは効率が良くないから、ブラウザで見たい!」

という現場からの要望がありました。

ということで、DXF TIIPのファイルをブラウザ上で閲覧できる簡易ビューワーを作りました!(1年ぐらい前に)
突貫工事で作ったのであまりできはよくないですが、ザックリとファイルの中身を 見られるので重宝していただいてます。

DXF TIIP Viewer - Github

DXF TIIP Viewer

シタテルの SCSやマイオペレーター、マイアトリエにも組み込まれています。スマホでも見られるので外出先でちょっと確認したいときにも便利です。

フォーマットが見つからなかった、、、

実装するときにファイルフォーマットをダウンロードしよう思ったのですが、ちょっと探しただけでは見つけられず。

いや、きっと私の探し方が悪かっただけだと思うんですが、、、

結果、バイナリエディタとにらめっこしながらなんとなくで作りました。

TIIPはDXFのコメントエントリ(用語適当です、ごめんなさい)の部分を拡張してあるフォーマットだったので、なんとなくで読み取ることができました。

DXFの読み取り

DXF自体の読み込みには three-dxf を利用しました。
そのままだと読み取りできない部分があったのでもとのリポジトリをフォークして少し編集しています。

Three DXF - Github

おわりに

今回のDXFの話はちょっとした部分を便利にしただけですが、 シタテルではこのように現場の声を毎日聞きながらエンジニアが開発を行うことで、現場にフィットした機能を作り、効率性を高めることで多くの相談をすばやく処理して、ユーザー様の衣服づくりをサポートしています。

2018年10月29日月曜日

シタテルの技術ブログについて

10月 29, 2018

こんにちは!
シタテル株式会社CTOの和泉です。

今日はシタテルの技術ブログの管理について紹介します。
シタテルは衣服づくりのプラットフォームを提供しているスタートアップ企業ですが、
実は3分の1以上がエンジニア、デザイナーというIT企業でもあります。
(あまり知られてないので主張します!)

突然ですが、ここで質問です!
プログラマの好きなもの3つはなんでしょう?

答えは!?

GitHub
マークダウン
デプロイ自動化

ですよね!そうに違いない!

この独断と偏見に基づいて、シタテルの技術ブログはマークダウンで記述して、GitHubで管理レビューをして、
CircleCIによって自動的にデプロイされる仕掛けにしてみました。

この仕組で社内のメンバーの皆さんに1スプリントに1ブログをお願いしています。

さて、今回はその 仕組みと投稿の手順を簡単に紹介します。

しくみ

仕組みと行っても難しいことをしているわけではないのですが、、、

APIの充実したブログサービスとして、知識のない私はBloggerしか思いつきませんでした。

しかし、Bloggerはマークダウンでは投稿できません。なので、マークダウンで記述したファイルをプログラムでHTMLに変換しています。

また、画像等のファイルは マークダウンで書いたテキストそのままを投稿してもどうにもなりませんので、変換後のHTMLのDOM構造からリンクURLを抽出してAmazon S3にアップロード&URLの書き換えを行っています。

以下の手順に出てくるURLはシタテル社員限定公開なのですが、
こちらの公開リポジトリでその部分のコードはご覧いただけます。

https://github.com/shinobushiva/blogautomation

手順

前準備(初回のみ)

1. https://github.com/sitateru/tech-blog をクローン

git clone https://github.com/sitateru/tech-blog

2. masterブランチから新しいブランチを作成してチェックアウト

git branch shinobu.izumi
git checkout shinobu.izumi

ここでは例として shinobu.izumi というブランチを作っています。

ブランチは1人1つを使いまわしても、各自が記事ごとに切るなどしても構いません。

3. posts/blog/ 配下に個人のフォルダを作成(フォルダ名は個人が特定しやすい名前にしてください)

フォルダ作成
ここでは例として shinobu.izumi というフォルダを作っています。

新しい記事を追加する場合

0. masterブランチをpull

最新のmasterブランチを忘れずにpullします。

1. 自身のフォルダ内に記事のフォルダを作成(フォルダ名は自由)

記事のフォルダ作成

2. フォルダ内に記事を作成

最低限必要なファイルは content.mdmeta.json です。

content.md

投稿する記事の内容をマークダウン形式で記述します。

meta.json

記事のメタ情報を記述します。親フォルダの内容を継承しますが、子フォルダの内容で上書きされます。

例は最後に記述してあります。

3. ブランチをリモートリポジトリにプッシュ

git push origin shinobu.izumi

4. publish ブランチ向けにPR

GitHub上で publishブランチに向けてPRを出します。
レビュー後にマージします。

meta.json 例

{
    "blogId": "1797929185044797553",
    "isDraft": true,
    "publish": false,
    "revert": false,

    "isPage": false,
    "ignore": false,
    "forcePost": false,
    "contentPath": "content.md"
}
{
    "ignore": false,
    "resource": {
        "title": "シタテルのオンライン衣服生産システム"
    }
}

以下はBloggerAPIへの指定パラメーター(の一部)です。

キー 意味
blogId 投稿対象とするブログのIDです
isDraft true - 下書きとして投稿します
publish true - 下書きのものを公開に変更します
revert true - 公開のものを下書きに変更します
resource.title 記事のタイトルを指定します

以下は本システム向けの設定です。

キー 意味
isPage true - ページとして投稿, false - 記事として投稿
ignore true - そのフォルダの記事に対する処理を無視
forcePost true - すでに記事が存在している場合でも新しく記事を投稿
contentPath マークダウンファイルの名前(変更の必要なし)

記事のブログへの公開

publishブランチにマージすると、CircleCIが動いて自動的にブログに投稿します。
CircleCIの内部で公開日時などのメタ情報を更新したものをmasterブランチにプッシュします。これにより公開情報をGithubに記録しています。

おわりに

以上、シタテルの技術ブログの管理についてでした。

これから、シタテルで働いているメンバーが使っている技術や日々の業務の中で取り組んだ内容などをお伝えしていきます !