概要
D言語でもTravis-CIやCircle-CIをはじめとする各種CIサービスでテスト・デプロイが可能です。
今回はTravis-CIを用いてReleaseのデプロイを自動化するテンプレを紹介します。
ちなみにビルドにはdubを使う前提です。
- D言語+Travis-CIでテスト自動化する話➀
- D言語+Travis-CIでテスト自動化する話②
- D言語+Travis-CIでリリースのデプロイ自動化する話 ← この記事
- D言語+Travis-CIでドキュメントのデプロイ自動化する話
.travis.yml のテンプレ
.travis.yml
language: d
# ここにテストの記述
jobs:
include:
- stage: GitHub Release
d: ldc
os: linux
script: echo "Deploying to GitHub releases ..." && ./.travis-release.sh
deploy:
provider: releases
api_key: $GH_REPO_TOKEN
file_glob: true
file: <プロジェクト名>-*.tar.gz
after_success: true
skip_cleanup: true
on:
repo: <アカウント名>/<プロジェクト名>
tags: true
- stage: GitHub Release
d: ldc
os: osx
script: echo "Deploying to GitHub releases ..." && ./.travis-release.sh
deploy:
provider: releases
api_key: $GH_REPO_TOKEN
file_glob: true
file: gendoc-*.tar.gz
after_success: true
skip_cleanup: true
on:
repo: <アカウント名>/<プロジェクト名>
tags: true
- stage: GitHub Release
d: dmd
os: linux
language: generic
sudo: yes
script: echo "Deploying to GitHub releases ..." && ARCH=32 ./.travis-release-windows.sh
addons:
apt:
packages:
- p7zip-full
deploy:
provider: releases
api_key: $GH_REPO_TOKEN
file_glob: true
file: <プロジェクト名>-*.zip
after_success: true
skip_cleanup: true
on:
repo: <アカウント名>/<プロジェクト名>
tags: true
- stage: GitHub Release
d: dmd
os: linux
language: generic
sudo: yes
script: echo "Deploying to GitHub releases ..." && ARCH=64 ./.travis-release-windows.sh
addons:
apt:
packages:
- p7zip-full
deploy:
provider: releases
api_key: $GH_REPO_TOKEN
file_glob: true
file: <プロジェクト名>-*.zip
after_success: true
skip_cleanup: true
on:
repo: <アカウント名>/<プロジェクト名>
tags: true
解説
この設定で、タグをつけてpushした際に、GitHubのReleaseページに以下4つのアーカイブファイルを追加することができます。
OS | アーキテクチャ | ファイル名 |
---|---|---|
Linux | x86_64 | <プロジェクト名>-<バージョン>-linux-x86_64.tar.gz |
OSX | x86_64 | <プロジェクト名>-<バージョン>-osx-x86_64.tar.gz |
Windows | x86_64 | <プロジェクト名>-<バージョン>-windows-x86_64.tar.gz |
Windows | x86 | <プロジェクト名>-<バージョン>-windows-x86.tar.gz |
ポイントは以下:
- $GH_REPO_TOKEN はデプロイに必要なトークン。
GitHubにて、ユーザーアカウントの「Settings」→「Developer settings」→「Personal access tokens」へとたどり発行できます。権限はSelect scopesで設定し、「repo_deployment / Access deployment status」をチェックします。
このキーをTravis-CIの各リポジトリの設定で「more options」→「Environment Variables」の欄に登録します。 -
./.travis-release.sh
は、Linux / OSX 向け -
./.travis-release-windows.sh
および./.travis-release-windows-setup.sh
はWindows向け(Travis-CIのLinuxサーバー上でクロスコンパイルする)です。 - Windows向けでは後述の7z解凍用に
p7zip-full
が必要です。 - 上記テンプレの設定の場合、毎回ビルド(アーカイブの作成)は行うが、デプロイはしない、という設定になる。「テストは通っているけどアーカイブにする段になって何かしら問題が生じたためタグをつけたのにデプロイできず、さらにはタグをつけたところが build failed になる」という恥ずかしい状況を防ぐのに効果があると思います。
- 毎回ビルドしたくない場合 → TravisCI タグをプッシュした時だけ動くビルドステージの設定 By @masakurapa
以下実際のプロジェクトで使われている設定です。大いに参考にしました。
.travis-release.sh
#!/usr/bin/env bash
set -eux -o pipefail
PROJECTNAME=<プロジェクト名>
VERSION=$(git describe --abbrev=0 --tags)
ARCH="${ARCH:-64}"
LDC_FLAGS=()
unameOut="$(uname -s)"
case "$unameOut" in
Linux*) OS=linux; LDC_FLAGS=("-flto=full" "-linker=gold" "-static") ;;
Darwin*) OS=osx; LDC_FLAGS+=("-L-macosx_version_min" "-L10.7" "-L-lcrt1.o"); ;;
*) echo "Unknown OS: $unameOut"; exit 1
esac
case "$ARCH" in
x86_64) ARCH_SUFFIX="x86_64";;
64) ARCH_SUFFIX="x86_64";;
i386) ARCH_SUFFIX="x86";;
i686) ARCH_SUFFIX="x86";;
x86) ARCH_SUFFIX="x86";;
32) ARCH_SUFFIX="x86";;
*) echo "Unknown ARCH: $ARCH"; exit 1
esac
archiveName="$PROJECTNAME-$VERSION-$OS-$ARCH_SUFFIX.tar.gz"
echo "Building $archiveName"
dub build -b=release
cd build
tar cvfz "../$archiveName" -C . *
cd ..
ポイントは以下:
-
PROJECTNAME=<プロジェクト名>
としているところでプロジェクト名を入力します。アーカイブ名に使われます。 -
dub build -b=release
でビルド。このプロジェクトはtargetPath
にbuild
を指定しているので、buildディレクトリ以下をアーカイブする。 -
cd build
~cd ..
の箇所はアーカイブを作成するところ。ライセンスを入れたりディレクトリの構造いじったりする場合はここでやります。
.travis-release-windows.sh, .travis-release-windows-setup.sh
.travis-release-windows.sh
#!/usr/bin/env bash
# Build the Windows binaries under Linux
set -eux -o pipefail
PROJECTNAME=<プロジェクト名>
# Allow the script to be run from anywhere
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $DIR
source .travis-release-windows-setup.sh
# Run LDC with cross-compilation
archiveName="$PROJECTNAME-$VERSION-$OS-$ARCH_SUFFIX.zip"
echo "Building $archiveName"
dub build -a=$TARGET_MTRIPLE -b=release -c=default --compiler=ldc2
cd build
zip -r "../$archiveName" "./"
cd ..
※リリース前・マージ後のやり方
.travis-release-windows.sh
#!/usr/bin/env bash
# Build the Windows binaries under Linux
set -eux -o pipefail
PROJECTNAME=<プロジェクト名>
# Allow the script to be run from anywhere
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $DIR
source .travis-release-windows-setup.sh
# Run LDC with cross-compilation
archiveName="$PROJECTNAME-$VERSION-$OS-$ARCH_SUFFIX.zip"
echo "Building $archiveName"
git clone https://github.com/dlang/dub.git --depth=1 && dub run --root=dub -- build -a=$TARGET_MTRIPLE -b=release -c=default --compiler=ldc2
cd build
zip -r "../$archiveName" "./"
cd ..
- Windows向けのクロスコンパイルを行い、zipでアーカイブします。
-
ただし、現在 dub がクロスコンパイルに対応しておらず、Pull Requestが出ていますのでリリースを待ちましょう。- マージされました。次回リリースで導入されるでしょう。
- マージされたので、dubのmasterをcloneしてビルドしつつ、ビルドしたdubで
-a=$TARGET_MTRIPLE
を指定することでクロスコンパイルできるようにしています。 - リリースされました。 これに伴い、上記例も修正しました。v1.18.0より前のLDCを使用してクロスコンパイルをする場合は、「※リリース前・マージ後のやり方」を参考にして、デプロイ中にクロスコンパイル対応のdubをビルド・実行してください。
- makeなどを使う場合は、ここで
-mtriple=$TARGET_MTRIPLE
を指定したldc2でビルドすることでクロスコンパイルできます。ちなみに、後述しますが、途中で読んでいるsource .travis-release-windows-setup.sh
の部分で$TARGET_MTRIPLE
に適切な-mtriple
の値が設定されています。
以下実装例
.travis-release-windows-windows.sh
#!/usr/bin/env bash
# sets up LDC for cross-compilation. Source this script, s.t. the new LDC is in PATH
ARCH=${ARCH:-32}
VERSION=$(git describe --abbrev=0 --tags)
OS=windows
case "$ARCH" in
x86_64) ARCH_SUFFIX="x86_64";;
64) ARCH_SUFFIX="x86_64";;
i386) ARCH_SUFFIX="x86";;
i686) ARCH_SUFFIX="x86";;
x86) ARCH_SUFFIX="x86";;
32) ARCH_SUFFIX="x86";;
*) echo "Unknown ARCH: $ARCH"; exit 1
esac
# Step 0: install ldc
if [ ! -f install.sh ] ; then
wget https://dlang.org/install.sh
fi
LDC_VERSION=${LDC_VERSION:-$(bash ./install.sh -a ldc | sed -E 's/.+\/ldc-([0-9.]+)\/activate/\1/')}
. $(bash ./install.sh -a "ldc-${LDC_VERSION}")
# for the install.sh script only
LDC_PATH="$(dirname $(dirname $(which ldc2)))"
# Step 1a: download the LDC x64 windows binaries
if [ "${ARCH_SUFFIX}" == "x86_64" ] && [ ! -d "ldc2-${LDC_VERSION}-windows-x64" ] ; then
wget "https://github.com/ldc-developers/ldc/releases/download/v${LDC_VERSION}/ldc2-${LDC_VERSION}-windows-x64.7z"
7z x "ldc2-${LDC_VERSION}-windows-x64.7z" > /dev/null
# Step 2a: Add LDC windows binaries to LDC Linux
if [ ! -d "${LDC_PATH}/lib-win64" ] ; then
cp -r ldc2-${LDC_VERSION}-windows-x64/lib "${LDC_PATH}/lib-win64"
cat >> "$LDC_PATH"/etc/ldc2.conf <<EOF
"x86_64-.*-windows-msvc":
{
switches = [
"-defaultlib=phobos2-ldc,druntime-ldc",
"-link-defaultlib-shared=false",
];
lib-dirs = [
"%%ldcbinarypath%%/../lib-win64",
];
};
EOF
fi
fi
# Step 1b: download the LDC x86 windows binaries
if [ "${ARCH_SUFFIX}" == "x86" ] && [ ! -d "ldc2-${LDC_VERSION}-windows-x86" ] ; then
wget "https://github.com/ldc-developers/ldc/releases/download/v${LDC_VERSION}/ldc2-${LDC_VERSION}-windows-x86.7z"
7z x "ldc2-${LDC_VERSION}-windows-x86.7z" > /dev/null
# Step 2b: Add LDC windows binaries to LDC Linux
if [ ! -d "${LDC_PATH}/lib-win32" ] ; then
cp -r ldc2-${LDC_VERSION}-windows-x86/lib "${LDC_PATH}/lib-win32"
cat >> "$LDC_PATH"/etc/ldc2.conf <<EOF
"i686-.*-windows-msvc":
{
switches = [
"-defaultlib=phobos2-ldc,druntime-ldc",
"-link-defaultlib-shared=false",
];
lib-dirs = [
"%%ldcbinarypath%%/../lib-win32",
];
};
EOF
fi
fi
# set suffices and compilation flags
if [ "$ARCH_SUFFIX" == "x86_64" ] ; then
export TARGET_MTRIPLE="x86_64-windows-msvc"
else
export TARGET_MTRIPLE="i686-windows-msvc"
fi
ポイント(というか何をやっているかの概要)は以下
- インストールスクリプトでldc2をインストール
- Windows向けのldc2(中身のlibファイルが目当て)をダウンロード
- 配布形態の7zipを解凍してlibファイルをコピー(ここで先述のp7zip-fullが必要)
- ldc2.confにクロスコンパイル用の設定を追加(--windows-msvcのときのlibファイルの場所の指定など)
-
TARGET_MTRIPLE
環境変数に-mtriple=
の中身になるx86_64-windows-msvc
やi686-windows-msvc
を設定
以下実装例
ライセンス
今回紹介したスクリプトは多分 BSL-1.0 です。使用する場合はご注意ください。D-Scanner (BSD-1.0)で使われているスクリプトがベースになっています。