.gitlab-ci.yml 11 KB

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