.gitlab-ci.yml 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. stages:
  2. - test
  3. - deploy
  4. - container-build
  5. variables:
  6. DEBIAN_FRONTEND: noninteractive
  7. DEBIAN_OLD_STABLE: buster
  8. DEBIAN_STABLE: bullseye
  9. REPRODUCIBLE_FLAGS: -trimpath -ldflags=-buildid=
  10. # set up apt for automated use
  11. .apt-template: &apt-template
  12. - export LC_ALL=C.UTF-8
  13. - export DEBIAN_FRONTEND=noninteractive
  14. - echo Etc/UTC > /etc/timezone
  15. - echo 'quiet "1";'
  16. 'APT::Install-Recommends "0";'
  17. 'APT::Install-Suggests "0";'
  18. 'APT::Acquire::Retries "20";'
  19. 'APT::Get::Assume-Yes "true";'
  20. 'Dpkg::Use-Pty "0";'
  21. > /etc/apt/apt.conf.d/99gitlab
  22. - apt-get update
  23. - apt-get dist-upgrade
  24. # Set things up to use the OS-native packages for Go. Anything that
  25. # is downloaded by go during the `go fmt` stage is not coming from the
  26. # Debian/Ubuntu repo. So those would need to be packaged for this to
  27. # make it into Debian and/or Ubuntu.
  28. .debian-native-template: &debian-native-template
  29. variables:
  30. GOPATH: /usr/share/gocode
  31. before_script:
  32. - apt-get update
  33. - apt-get -qy install --no-install-recommends
  34. build-essential
  35. ca-certificates
  36. git
  37. golang
  38. golang-github-cheekybits-genny-dev
  39. golang-github-jtolds-gls-dev
  40. golang-github-klauspost-reedsolomon-dev
  41. golang-github-lucas-clemente-quic-go-dev
  42. golang-github-smartystreets-assertions-dev
  43. golang-github-smartystreets-goconvey-dev
  44. golang-github-tjfoc-gmsm-dev
  45. golang-github-xtaci-kcp-dev
  46. golang-github-xtaci-smux-dev
  47. golang-golang-x-crypto-dev
  48. golang-golang-x-net-dev
  49. golang-goptlib-dev
  50. golang-golang-x-sys-dev
  51. golang-golang-x-text-dev
  52. golang-golang-x-xerrors-dev
  53. lbzip2
  54. # use Go installed as part of the official, Debian-based Docker images
  55. .golang-docker-debian-template: &golang-docker-debian-template
  56. before_script:
  57. - apt-get update
  58. - apt-get -qy install --no-install-recommends
  59. ca-certificates
  60. git
  61. lbzip2
  62. .go-test: &go-test
  63. - gofmt -d .
  64. - test -z "$(go fmt ./...)"
  65. - go vet ./...
  66. - go test -v -race ./...
  67. - cd $CI_PROJECT_DIR/client/
  68. - go get
  69. - go build $REPRODUCIBLE_FLAGS
  70. .test-template: &test-template
  71. artifacts:
  72. name: "${CI_PROJECT_PATH}_${CI_JOB_STAGE}_${CI_JOB_ID}_${CI_COMMIT_REF_NAME}_${CI_COMMIT_SHA}"
  73. paths:
  74. - client/*.aar
  75. - client/*.jar
  76. - client/client
  77. expire_in: 1 week
  78. when: on_success
  79. after_script:
  80. - echo "Download debug artifacts from https://gitlab.com/${CI_PROJECT_PATH}/-/jobs"
  81. # this file changes every time but should not be cached
  82. - rm -f $GRADLE_USER_HOME/caches/modules-2/modules-2.lock
  83. - rm -rf $GRADLE_USER_HOME/caches/*/plugin-resolution/
  84. # -- jobs ------------------------------------------------------------
  85. android:
  86. image: golang:1.21-$DEBIAN_STABLE
  87. variables:
  88. ANDROID_HOME: /usr/lib/android-sdk
  89. LANG: C.UTF-8
  90. cache:
  91. paths:
  92. - .gradle/wrapper
  93. - .gradle/caches
  94. <<: *test-template
  95. before_script:
  96. - *apt-template
  97. - apt-get install
  98. android-sdk-platform-23
  99. android-sdk-platform-tools
  100. build-essential
  101. curl
  102. default-jdk-headless
  103. git
  104. gnupg
  105. unzip
  106. wget
  107. ca-certificates
  108. lbzip2
  109. - ndk=android-ndk-r21e-linux-x86_64.zip
  110. - wget --continue --no-verbose https://dl.google.com/android/repository/$ndk
  111. - echo "ad7ce5467e18d40050dc51b8e7affc3e635c85bd8c59be62de32352328ed467e $ndk" > $ndk.sha256
  112. - sha256sum -c $ndk.sha256
  113. - unzip -q $ndk
  114. - rm ${ndk}*
  115. - mv android-ndk-* $ANDROID_HOME/ndk-bundle/
  116. - chmod -R a+rX $ANDROID_HOME
  117. script:
  118. - *go-test
  119. - export GRADLE_USER_HOME=$CI_PROJECT_DIR/.gradle
  120. - go version
  121. - go env
  122. - go get golang.org/x/mobile/cmd/gomobile
  123. - go get golang.org/x/mobile/cmd/gobind
  124. - go install golang.org/x/mobile/cmd/gobind
  125. - go install golang.org/x/mobile/cmd/gomobile
  126. - gomobile init
  127. - cd $CI_PROJECT_DIR/client
  128. # gomobile builds a shared library not a CLI executable
  129. - sed -i 's,^package main$,package snowflakeclient,' *.go
  130. - go get golang.org/x/mobile/bind
  131. - gomobile bind -v -target=android $REPRODUCIBLE_FLAGS .
  132. go-1.21:
  133. image: golang:1.21-$DEBIAN_STABLE
  134. <<: *golang-docker-debian-template
  135. <<: *test-template
  136. script:
  137. - *go-test
  138. debian-testing:
  139. image: debian:testing
  140. <<: *debian-native-template
  141. <<: *test-template
  142. script:
  143. - *go-test
  144. shadow-integration:
  145. image: golang:1.21-$DEBIAN_STABLE
  146. variables:
  147. SHADOW_VERSION: "193924aae0dab30ffda0abe29467f552949849fa"
  148. TGEN_VERSION: "v1.1.2"
  149. cache:
  150. key: sf-integration-$SHADOW_VERSION-$TGEN_VERSION
  151. paths:
  152. - /opt/
  153. artifacts:
  154. paths:
  155. - shadow.data.tar.gz
  156. when: on_failure
  157. tags:
  158. - amd64
  159. - tpa
  160. script:
  161. - apt-get update
  162. - apt-get install -y git tor
  163. - mkdir -p ~/.local/bin
  164. - mkdir -p ~/.local/src
  165. - export PATH=$PATH:$CI_PROJECT_DIR/opt/bin/
  166. # Install shadow and tgen
  167. - pushd ~/.local/src
  168. - |
  169. if [ ! -f opt/shadow/bin/shadow ]
  170. then
  171. echo "The required version of shadow was not cached, building from source"
  172. git clone --shallow-since=2021-08-01 https://github.com/shadow/shadow.git
  173. pushd shadow/
  174. git checkout $SHADOW_VERSION
  175. CONTAINER=debian:stable-slim ci/container_scripts/install_deps.sh
  176. CC=gcc CONTAINER=debian:stable-slim ci/container_scripts/install_extra_deps.sh
  177. export PATH="$HOME/.cargo/bin:${PATH}"
  178. ./setup build --jobs $(nproc) --prefix $CI_PROJECT_DIR/opt/
  179. ./setup install
  180. popd
  181. fi
  182. - |
  183. if [ ! -f opt/shadow/bin/tgen ]
  184. then
  185. echo "The required version of tgen was not cached, building from source"
  186. git clone --branch $TGEN_VERSION --depth 1 https://github.com/shadow/tgen.git
  187. pushd tgen/
  188. apt-get install -y cmake libglib2.0-dev libigraph-dev
  189. mkdir build && cd build
  190. cmake .. -DCMAKE_INSTALL_PREFIX=$CI_PROJECT_DIR/opt/
  191. make
  192. make install
  193. popd
  194. fi
  195. install $CI_PROJECT_DIR/opt/bin/tgen ~/.local/bin/tgen
  196. - popd
  197. # Apply snowflake patch(es)
  198. - |
  199. git clone --depth 1 https://github.com/cohosh/shadow-snowflake-minimal
  200. git am -3 shadow-snowflake-minimal/*.patch
  201. # Install snowflake binaries to .local folder
  202. - |
  203. for app in "proxy" "client" "server" "broker" "probetest"; do
  204. pushd $app
  205. go build
  206. install $app ~/.local/bin/snowflake-$app
  207. popd
  208. done
  209. # Install stun server
  210. - GOBIN=~/.local/bin go install github.com/gortc/stund@latest
  211. # Run a minimal snowflake shadow experiment
  212. - pushd shadow-snowflake-minimal/
  213. - shadow --log-level=debug --model-unblocked-syscall-latency=true snowflake-minimal.yaml > shadow.log
  214. - tar -czvf $CI_PROJECT_DIR/shadow.data.tar.gz shadow.data/
  215. # Check to make sure streams succeeded
  216. - |
  217. if [ $(grep -c "stream-success" shadow.data/hosts/snowflakeclient/tgen.*.stdout) = 10 ]
  218. then
  219. echo "All streams in shadow completed successfully"
  220. else
  221. echo "Shadow simulation failed"
  222. exit 1
  223. fi
  224. generate_tarball:
  225. stage: deploy
  226. image: golang:1.21-$DEBIAN_STABLE
  227. rules:
  228. - if: $CI_COMMIT_TAG
  229. script:
  230. - go mod vendor
  231. - tar czf ${CI_PROJECT_NAME}-${CI_COMMIT_TAG}.tar.gz --transform "s,^,${CI_PROJECT_NAME}-${CI_COMMIT_TAG}/," *
  232. after_script:
  233. - echo TAR_JOB_ID=$CI_JOB_ID >> generate_tarball.env
  234. artifacts:
  235. paths:
  236. - ${CI_PROJECT_NAME}-${CI_COMMIT_TAG}.tar.gz
  237. reports:
  238. dotenv: generate_tarball.env
  239. release-job:
  240. stage: deploy
  241. image: registry.gitlab.com/gitlab-org/release-cli:latest
  242. rules:
  243. - if: $CI_COMMIT_TAG
  244. needs:
  245. - job: generate_tarball
  246. artifacts: true
  247. script:
  248. - echo "running release_job"
  249. release:
  250. name: 'Release $CI_COMMIT_TAG'
  251. description: 'Created using the release-cli'
  252. tag_name: '$CI_COMMIT_TAG'
  253. ref: '$CI_COMMIT_TAG'
  254. assets:
  255. links:
  256. - name: '${CI_PROJECT_NAME}-${CI_COMMIT_TAG}.tar.gz'
  257. url: '${CI_PROJECT_URL}/-/jobs/${TAR_JOB_ID}/artifacts/file/${CI_PROJECT_NAME}-${CI_COMMIT_TAG}.tar.gz'
  258. # Build the container only if the commit is to main, or it is a tag.
  259. # If the commit is to main, then the docker image tag should be set to `latest`.
  260. # If it is a tag, then the docker image tag should be set to the tag name.
  261. build-container:
  262. variables:
  263. TAG: $CI_COMMIT_TAG # Will not be set on a non-tag build, will be set later
  264. stage: container-build
  265. parallel:
  266. matrix:
  267. - ARCH: amd64
  268. - ARCH: arm64
  269. - ARCH: s390x
  270. tags:
  271. - $ARCH
  272. image:
  273. name: gcr.io/kaniko-project/executor:debug
  274. entrypoint: [""]
  275. script:
  276. - if [ $CI_COMMIT_REF_NAME == "main" ]; then export TAG='latest'; fi
  277. - >-
  278. echo "Building Docker image with tag: $TAG"
  279. /kaniko/executor
  280. --context "${CI_PROJECT_DIR}"
  281. --dockerfile "${CI_PROJECT_DIR}/Dockerfile"
  282. --destination "${CI_REGISTRY_IMAGE}:${TAG}_${ARCH}"
  283. rules:
  284. - if: $CI_COMMIT_REF_NAME == "main"
  285. - if: $CI_COMMIT_TAG
  286. merge-manifests:
  287. variables:
  288. TAG: $CI_COMMIT_TAG
  289. stage: container-build
  290. needs:
  291. - job: build-container
  292. artifacts: false
  293. image:
  294. name: mplatform/manifest-tool:alpine
  295. entrypoint: [""]
  296. script:
  297. - if [ $CI_COMMIT_REF_NAME == "main" ]; then export TAG='latest'; fi
  298. - >-
  299. manifest-tool
  300. --username="${CI_REGISTRY_USER}"
  301. --password="${CI_REGISTRY_PASSWORD}"
  302. push from-args
  303. --platforms linux/amd64,linux/arm64,linux/s390x
  304. --template "${CI_REGISTRY_IMAGE}:${TAG}_ARCH"
  305. --target "${CI_REGISTRY_IMAGE}:${TAG}"
  306. rules:
  307. - if: $CI_COMMIT_REF_NAME == "main"
  308. when: always
  309. - if: $CI_COMMIT_TAG
  310. when: always
  311. # If this is a tag, then we want to additionally tag the image as `stable`
  312. tag-container-release:
  313. stage: container-build
  314. image: quay.io/podman/stable
  315. allow_failure: false
  316. variables:
  317. IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG
  318. RELEASE_TAG: $CI_REGISTRY_IMAGE:stable
  319. script:
  320. - echo "Tagging docker image with stable tag"
  321. - echo -n "$CI_JOB_TOKEN" | podman login -u gitlab-ci-token --password-stdin $CI_REGISTRY
  322. - podman pull $IMAGE_TAG || true
  323. - podman tag $IMAGE_TAG $RELEASE_TAG
  324. - podman push $RELEASE_TAG
  325. rules:
  326. - if: $CI_COMMIT_TAG
  327. when: always
  328. clean-image-tags:
  329. stage: container-build
  330. needs:
  331. - job: merge-manifests
  332. artifacts: false
  333. image: containers.torproject.org/tpo/tpa/base-images:bookworm
  334. before_script:
  335. - *apt-template
  336. - apt-get install -y jq curl
  337. script:
  338. - "REGISTRY_ID=$(curl --silent --request GET --header \"JOB-TOKEN: ${CI_JOB_TOKEN}\" \"https://gitlab.torproject.org/api/v4/projects/${CI_PROJECT_ID}/registry/repositories\" | jq '.[].id')"
  339. - "curl --request DELETE --data \"name_regex_delete=(latest|${CI_COMMIT_TAG})_.*\" --header \"JOB-TOKEN: ${CI_JOB_TOKEN}\" \"https://gitlab.torproject.org/api/v4/projects/${CI_PROJECT_ID}/registry/repositories/${REGISTRY_ID}/tags\""
  340. rules:
  341. - if: $CI_COMMIT_REF_NAME == "main"
  342. when: always
  343. - if: $CI_COMMIT_TAG
  344. when: always