Skip to content

Commit 4b64d6f

Browse files
committed
Migrate to github CI
1 parent 6f55ccb commit 4b64d6f

17 files changed

+723
-1257
lines changed

.cirrus.yml

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
freebsd_instance:
2+
image_family: freebsd-13-1
3+
disk: 100
4+
5+
task:
6+
timeout_in: 120m
7+
env:
8+
AWS_ACCESS_KEY_ID: ENCRYPTED[7e381ce808bf572cdde8ea4b7023d06b631844d3dabfdb193b15e76a78555ad7f605afc34d8a51c69ab1b277c3c2e304]
9+
AWS_SECRET_ACCESS_KEY: ENCRYPTED[640639db00f954f466c90613b79ae3b364268cd153c7e4f8cab16c75c2bdf72c9ffe18f14b4f0ae2fc0bdf21beadb3f2]
10+
S3_HOST: ENCRYPTED[ef3162480f5b404ac20c12fb8cb55b664102463cea1b49cec4260b67e22f0b4b8da51c9c547a5c3da8ef22146459e324]
11+
TARBALL_EXT: "tar.xz"
12+
ARCH: 64
13+
ARTIFACT: "x86_64-freebsd"
14+
DISTRO: "na"
15+
RUNNER_OS: "FreeBSD"
16+
ADD_CABAL_ARGS: "--enable-split-sections"
17+
GITHUB_WORKSPACE: ${CIRRUS_WORKING_DIR}
18+
install_script: pkg install -y hs-cabal-install git bash misc/compat10x misc/compat11x misc/compat12x gmake patchelf
19+
script:
20+
- bash .github/scripts/build.sh
21+
binaries_artifacts:
22+
path: "out/*"
23+

.github/scripts/build.sh

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#!/bin/bash
2+
3+
set -eux
4+
5+
. .github/scripts/prereq.sh
6+
. .github/scripts/common.sh
7+
8+
9+
# ensure ghcup
10+
if ! command -v ghcup ; then
11+
install_ghcup
12+
fi
13+
14+
# ensure cabal-cache
15+
if ! cabal-cache version ; then
16+
download_cabal_cache "$HOME/.local/bin/cabal-cache"
17+
fi
18+
19+
20+
# build
21+
ecabal update
22+
23+
case "$(uname)" in
24+
MSYS_*|MINGW*)
25+
for ghc in $(cat bindist/ghcs-Msys) ; do
26+
GHC_VERSION="${ghc%,*}"
27+
args=( -O2 -w "ghc-$GHC_VERSION" --project-file cabal.project --disable-profiling --disable-tests --enable-executable-stripping ${ADD_CABAL_ARGS})
28+
ghcup install ghc "${GHC_VERSION}"
29+
"ghc-${GHC_VERSION}" --info
30+
# Shorten binary names
31+
sed -i.bak -e 's/haskell-language-server/hls/g' \
32+
-e 's/haskell_language_server/hls/g' \
33+
haskell-language-server.cabal cabal.project
34+
sed -i.bak -e 's/Paths_haskell_language_server/Paths_hls/g' \
35+
src/**/*.hs exe/*.hs
36+
37+
38+
# shellcheck disable=SC2068
39+
build_with_cache ${args[@]} exe:hls exe:hls-wrapper
40+
41+
mkdir -p "$CI_PROJECT_DIR/out"
42+
43+
# shellcheck disable=SC2068
44+
cp "$(cabal list-bin -v0 ${args[@]} exe:hls)" "$CI_PROJECT_DIR/out/haskell-language-server-${GHC_VERSION}"${ext}
45+
# shellcheck disable=SC2068
46+
cp "$(cabal list-bin -v0 ${args[@]} exe:hls-wrapper)" "$CI_PROJECT_DIR/out/haskell-language-server-wrapper"${ext}
47+
ghcup rm ghc "${GHC_VERSION}"
48+
done
49+
;;
50+
*)
51+
sed -i.bak -e '/DELETE MARKER FOR CI/,/END DELETE/d' cabal.project # see comment in cabal.project
52+
emake --version
53+
emake GHCUP=ghcup CABAL_CACHE_BIN=cabal-cache S3_HOST="${S3_HOST}" S3_KEY="${ARTIFACT}" hls
54+
emake GHCUP=ghcup bindist
55+
rm -rf out/*.*.*
56+
;;
57+
esac
58+
59+
cp dist-newstyle/cache/plan.json "$CI_PROJECT_DIR/out/plan.json"
60+
61+
62+
# create tarball/zip
63+
TARBALL_PREFIX="haskell-language-server"
64+
case "${TARBALL_EXT}" in
65+
zip)
66+
HLS_VERSION="$("$CI_PROJECT_DIR/out/haskell-language-server-8.10.7" --numeric-version)"
67+
cd "$CI_PROJECT_DIR/out/"
68+
zip "${TARBALL_PREFIX}-${HLS_VERSION}-${ARTIFACT}.zip" haskell-language-server-*
69+
find . -type f ! -name '*.zip' -delete
70+
;;
71+
tar.xz)
72+
emake --version
73+
HLS_VERSION="$(emake -s -C out/bindist/haskell-language-server-* version)"
74+
emake TARBALL="${TARBALL_PREFIX}-${HLS_VERSION}-${ARTIFACT}.tar.xz" bindist-tar
75+
rm -rf out/bindist
76+
;;
77+
*)
78+
fail "Unknown TARBALL_EXT: ${TARBALL_EXT}"
79+
;;
80+
esac
81+

.github/scripts/common.sh

+231
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
#!/bin/sh
2+
3+
if [ "${RUNNER_OS}" = "Windows" ] ; then
4+
ext=".exe"
5+
else
6+
ext=''
7+
fi
8+
9+
# Colors
10+
BLACK="0;30"
11+
GRAY="1;30"
12+
RED="0;31"
13+
LT_RED="1;31"
14+
BROWN="0;33"
15+
LT_BROWN="1;33"
16+
GREEN="0;32"
17+
LT_GREEN="1;32"
18+
BLUE="0;34"
19+
LT_BLUE="1;34"
20+
PURPLE="0;35"
21+
LT_PURPLE="1;35"
22+
CYAN="0;36"
23+
LT_CYAN="1;36"
24+
WHITE="1;37"
25+
LT_GRAY="0;37"
26+
27+
ecabal() {
28+
cabal "$@"
29+
}
30+
31+
sync_from() {
32+
if [ "${RUNNER_OS}" != "Windows" ] ; then
33+
cabal_store_path="$(dirname "$(cabal help user-config | tail -n 1 | xargs)")/store"
34+
fi
35+
36+
cabal-cache sync-from-archive \
37+
--host-name-override="${S3_HOST}" \
38+
--host-port-override=443 \
39+
--host-ssl-override=True \
40+
--region us-west-2 \
41+
$([ "${RUNNER_OS}" != "Windows" ] && echo --store-path="$cabal_store_path") \
42+
--archive-uri "s3://haskell-language-server/${ARTIFACT}"
43+
}
44+
45+
sync_to() {
46+
if [ "${RUNNER_OS}" != "Windows" ] ; then
47+
cabal_store_path="$(dirname "$(cabal help user-config | tail -n 1 | xargs)")/store"
48+
fi
49+
50+
cabal-cache sync-to-archive \
51+
--host-name-override="${S3_HOST}" \
52+
--host-port-override=443 \
53+
--host-ssl-override=True \
54+
--region us-west-2 \
55+
$([ "${RUNNER_OS}" != "Windows" ] && echo --store-path="$cabal_store_path") \
56+
--archive-uri "s3://haskell-language-server/${ARTIFACT}"
57+
}
58+
59+
raw_eghcup() {
60+
"$GHCUP_BIN/ghcup${ext}" -v -c "$@"
61+
}
62+
63+
eghcup() {
64+
if [ "${OS}" = "Windows" ] ; then
65+
"$GHCUP_BIN/ghcup${ext}" -c -s "file:/$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml" "$@"
66+
else
67+
"$GHCUP_BIN/ghcup${ext}" -c -s "file://$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml" "$@"
68+
fi
69+
}
70+
71+
sha_sum() {
72+
if [ "${OS}" = "FreeBSD" ] ; then
73+
sha256 "$@"
74+
else
75+
sha256sum "$@"
76+
fi
77+
78+
}
79+
80+
git_describe() {
81+
git config --global --get-all safe.directory | grep '^\*$' || git config --global --add safe.directory "*"
82+
git describe --always
83+
}
84+
85+
download_cabal_cache() {
86+
(
87+
set -e
88+
dest="$HOME/.local/bin/cabal-cache"
89+
url=""
90+
exe=""
91+
cd /tmp
92+
case "${RUNNER_OS}" in
93+
"Linux")
94+
case "${DISTRO}" in
95+
"Alpine")
96+
case "${ARCH}" in
97+
"32") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/1.0.5.1/i386-linux-alpine-cabal-cache-1.0.5.1
98+
;;
99+
"64") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/1.0.5.1/x86_64-linux-alpine-static-cabal-cache-1.0.5.1
100+
;;
101+
esac
102+
;;
103+
*)
104+
case "${ARCH}" in
105+
"64") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/1.0.5.1/x86_64-linux-alpine-static-cabal-cache-1.0.5.1
106+
;;
107+
"ARM64") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/1.0.5.1/aarch64-linux-cabal-cache-1.0.5.1
108+
;;
109+
"ARM") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/1.0.5.1/armv7-linux-cabal-cache-1.0.5.1
110+
;;
111+
esac
112+
;;
113+
esac
114+
;;
115+
"FreeBSD")
116+
url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/1.0.5.1/x86_64-freebsd-cabal-cache-1.0.5.1
117+
;;
118+
"Windows")
119+
exe=".exe"
120+
url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/1.0.5.1/x86_64-mingw64-cabal-cache-1.0.5.1.exe
121+
;;
122+
"macOS")
123+
case "${ARCH}" in
124+
"ARM64") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/1.0.5.1/aarch64-apple-darwin-cabal-cache-1.0.5.1
125+
;;
126+
"64") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/1.0.5.1/x86_64-apple-darwin-cabal-cache-1.0.5.1
127+
;;
128+
esac
129+
;;
130+
esac
131+
132+
if [ -n "${url}" ] ; then
133+
case "${url##*.}" in
134+
"gz")
135+
curl -L -o - "${url}" | gunzip > cabal-cache${exe}
136+
;;
137+
*)
138+
curl -o cabal-cache${exe} -L "${url}"
139+
;;
140+
esac
141+
chmod +x cabal-cache${exe}
142+
cp "cabal-cache${exe}" "${dest}${exe}"
143+
fi
144+
)
145+
}
146+
147+
build_with_cache() {
148+
ecabal configure "$@"
149+
ecabal build --dependencies-only "$@" --dry-run
150+
sync_from
151+
ecabal build --dependencies-only "$@" || sync_to
152+
sync_to
153+
ecabal build "$@"
154+
sync_to
155+
}
156+
157+
install_ghcup() {
158+
find "$GHCUP_INSTALL_BASE_PREFIX"
159+
mkdir -p "$GHCUP_BIN"
160+
mkdir -p "$GHCUP_BIN"/../cache
161+
162+
if [ "${RUNNER_OS}" = "FreeBSD" ] ; then
163+
curl -o ghcup https://downloads.haskell.org/ghcup/tmp/x86_64-portbld-freebsd-ghcup-0.1.18.1
164+
chmod +x ghcup
165+
mv ghcup "$HOME/.local/bin/ghcup"
166+
else
167+
curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh
168+
fi
169+
}
170+
171+
strip_binary() {
172+
(
173+
set -e
174+
binary=$1
175+
if [ "${RUNNER_OS}" = "macOS" ] ; then
176+
strip "${binary}"
177+
else
178+
if [ "${RUNNER_OS}" != "Windows" ] ; then
179+
strip -s "${binary}"
180+
fi
181+
fi
182+
)
183+
}
184+
185+
# GitLab Pipelines log section delimiters
186+
# https://gitlab.com/gitlab-org/gitlab-foss/issues/14664
187+
start_section() {
188+
name="$1"
189+
echo -e "section_start:$(date +%s):$name\015\033[0K"
190+
}
191+
192+
end_section() {
193+
name="$1"
194+
echo -e "section_end:$(date +%s):$name\015\033[0K"
195+
}
196+
197+
echo_color() {
198+
local color="$1"
199+
local msg="$2"
200+
echo -e "\033[${color}m${msg}\033[0m"
201+
}
202+
203+
error() { echo_color "${RED}" "$1"; }
204+
warn() { echo_color "${LT_BROWN}" "$1"; }
205+
info() { echo_color "${LT_BLUE}" "$1"; }
206+
207+
fail() { error "error: $1"; exit 1; }
208+
209+
run() {
210+
info "Running $*..."
211+
"$@" || ( error "$* failed"; return 1; )
212+
}
213+
214+
emake() {
215+
if command -v gmake >/dev/null 2>&1 ; then
216+
gmake "$@"
217+
else
218+
make "$@"
219+
fi
220+
}
221+
222+
mktempdir() {
223+
case "$(uname -s)" in
224+
"Darwin"|"darwin")
225+
mktemp -d -t hls_ci.XXXXXXX
226+
;;
227+
*)
228+
mktemp -d
229+
;;
230+
esac
231+
}

.github/scripts/prereq.sh

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/bin/sh
2+
3+
mkdir -p "$HOME"/.local/bin
4+
5+
export PATH="$HOME/.local/bin:$PATH"
6+
7+
export BOOTSTRAP_HASKELL_NONINTERACTIVE=1
8+
export BOOTSTRAP_HASKELL_GHC_VERSION="${GHC_VER:-recommended}"
9+
export BOOTSTRAP_HASKELL_CABAL_VERSION="${CABAL_VER:-recommended}"
10+
export BOOTSTRAP_HASKELL_ADJUST_CABAL_CONFIG=yes
11+
12+
if [ "${RUNNER_OS}" = "Windows" ] ; then
13+
# on windows use pwd to get unix style path
14+
CI_PROJECT_DIR="$(pwd)"
15+
export CI_PROJECT_DIR
16+
export GHCUP_INSTALL_BASE_PREFIX="/c"
17+
export GHCUP_BIN="$GHCUP_INSTALL_BASE_PREFIX/ghcup/bin"
18+
export PATH="$GHCUP_BIN:$PATH"
19+
export CABAL_DIR="C:\\Users\\runneradmin\\AppData\\Roaming\\cabal"
20+
else
21+
export CI_PROJECT_DIR="${GITHUB_WORKSPACE}"
22+
export GHCUP_INSTALL_BASE_PREFIX="$CI_PROJECT_DIR"
23+
export GHCUP_BIN="$GHCUP_INSTALL_BASE_PREFIX/.ghcup/bin"
24+
export PATH="$GHCUP_BIN:$PATH"
25+
export CABAL_DIR="$CI_PROJECT_DIR/cabal"
26+
export CABAL_CACHE="$CI_PROJECT_DIR/cabal-cache"
27+
fi
28+
29+
export DEBIAN_FRONTEND=noninteractive
30+
export TZ=Asia/Singapore
31+
32+
if [ "${RUNNER_OS}" = "macOS" ] ; then
33+
if ! command -v brew ; then
34+
[ -e "$HOME/.brew" ] ||
35+
git clone --depth=1 https://github.com/Homebrew/brew "$HOME/.brew"
36+
export PATH="$HOME/.brew/bin:$HOME/.brew/sbin:$PATH"
37+
brew update
38+
fi
39+
if ! command -v git ; then
40+
brew install git
41+
fi
42+
if ! command -v realpath ; then
43+
brew install coreutils
44+
fi
45+
46+
brew install autoconf automake make tree
47+
if [ "${ARCH}" = "ARM64" ] ; then
48+
brew install llvm@11
49+
export PATH="$HOME/.brew/opt/llvm@11/bin:$PATH"
50+
export CC="$HOME/.brew/opt/llvm@11/bin/clang"
51+
export CXX="$HOME/.brew/opt/llvm@11/bin/clang++"
52+
export LD=ld
53+
export AR="$HOME/.brew/opt/llvm@11/bin/llvm-ar"
54+
export RANLIB="$HOME/.brew/opt/llvm@11/bin/llvm-ranlib"
55+
fi
56+
fi
57+

0 commit comments

Comments
 (0)