Skip to content

Commit 47fb33b

Browse files
committed
Introduce CI with GitHub Actions
Add CI using GitHub Actions and GitHub Packages: * This moves our Linux build containers into GitHub Packages; we will identify the most recent commit that updated the docker descriptions, and then look for a docker image in libgit2's GitHub Packages registry for a container with the tag corresponding to that description. If there is not one, we will build the container and then push it to GitHub Packages. * We no longer need to manage authentication with our own credentials or PAT tokens. GitHub Actions provides a GITHUB_TOKEN that can publish artifacts, packages and commits to our repository within a workflow run. * We will use a matrix to build our various CI steps. This allows us to keep configuration in a single place without multiple YAML files.
1 parent 4852d8d commit 47fb33b

File tree

4 files changed

+263
-2
lines changed

4 files changed

+263
-2
lines changed

.github/workflows/main.yml

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
# Continuous integration and pull request validation builds for the
2+
# master and maintenance branches.
3+
name: CI Build
4+
5+
on:
6+
push:
7+
branches: [ master, maint/* ]
8+
pull_request:
9+
branches: [ master, maint/* ]
10+
11+
env:
12+
docker-registry: docker.pkg.github.com
13+
docker-config-path: azure-pipelines/docker
14+
15+
jobs:
16+
# Build the docker container images that we will use for our Linux
17+
# builds. This will identify the last commit to the repository that
18+
# updated the docker images, and try to download the image tagged with
19+
# that sha. If it does not exist, we'll do a docker build and push
20+
# the image up to GitHub Packages for the actual CI/CD runs. We tag
21+
# with both the sha and "latest" so that the subsequent runs need not
22+
# know the sha. Only do this on CI builds (when the event is a "push")
23+
# because PR builds from forks lack permission to write packages.
24+
build_containers:
25+
name: Create docker image
26+
strategy:
27+
matrix:
28+
container:
29+
- xenial
30+
- bionic
31+
- docurium
32+
runs-on: ubuntu-latest
33+
steps:
34+
- name: Check out repository
35+
uses: actions/checkout@v2
36+
with:
37+
fetch-depth: 0
38+
if: github.event_name == 'push'
39+
- name: Download existing container
40+
run: azure-pipelines/getcontainer.sh ${{ env.docker-config-path }}/${{ matrix.container }}
41+
env:
42+
DOCKER_REGISTRY: ${{ env.docker-registry }}
43+
GITHUB_TOKEN: ${{ secrets.github_token }}
44+
if: github.event_name == 'push'
45+
- name: Build and publish image
46+
run: |
47+
docker build -t ${{ env.docker-registry-container-sha }} --build-arg BASE=${{ matrix.container.base }} -f ${{ matrix.container }} .
48+
docker push ${{ env.docker-registry-container-sha }}
49+
working-directory: ${{ env.docker-config-path }}
50+
if: github.event_name == 'push' && env.docker-container-exists != 'true'
51+
52+
# Run our CI/CD builds. We build a matrix with the various build targets
53+
# and their details. Then we build either in a docker container (Linux)
54+
# or on the actual hosts (macOS, Windows).
55+
build:
56+
name: Build
57+
needs: [build_containers]
58+
strategy:
59+
matrix:
60+
platform:
61+
- # Xenial, GCC, OpenSSL
62+
image: xenial
63+
env:
64+
CC: gcc
65+
CMAKE_GENERATOR: Ninja
66+
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON
67+
os: ubuntu-latest
68+
- # Xenial, GCC, mbedTLS
69+
image: xenial
70+
env:
71+
CC: gcc
72+
CMAKE_GENERATOR: Ninja
73+
CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON
74+
os: ubuntu-latest
75+
- # Xenial, Clang, OpenSSL
76+
image: xenial
77+
env:
78+
CC: clang
79+
CMAKE_GENERATOR: Ninja
80+
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON
81+
os: ubuntu-latest
82+
- # Xenial, Clang, mbedTLS
83+
image: xenial
84+
env:
85+
CC: clang
86+
CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON
87+
CMAKE_GENERATOR: Ninja
88+
os: ubuntu-latest
89+
- # macOS
90+
os: macos-10.15
91+
env:
92+
CC: clang
93+
CMAKE_OPTIONS: -DREGEX_BACKEND=regcomp_l -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=leaks -DUSE_GSSAPI=ON
94+
CMAKE_GENERATOR: Ninja
95+
PKG_CONFIG_PATH: /usr/local/opt/openssl/lib/pkgconfig
96+
SKIP_SSH_TESTS: true
97+
SKIP_NEGOTIATE_TESTS: true
98+
setup-script: osx
99+
- # Windows amd64 Visual Studio
100+
os: windows-2019
101+
env:
102+
ARCH: amd64
103+
CMAKE_GENERATOR: Visual Studio 16 2019
104+
CMAKE_OPTIONS: -A x64 -DMSVC_CRTDBG=ON -DDEPRECATE_HARD=ON
105+
SKIP_SSH_TESTS: true
106+
SKIP_NEGOTIATE_TESTS: true
107+
- # Windows x86 Visual Studio
108+
os: windows-2019
109+
env:
110+
ARCH: x86
111+
CMAKE_GENERATOR: Visual Studio 16 2019
112+
CMAKE_OPTIONS: -A Win32 -DMSVC_CRTDBG=ON -DDEPRECATE_HARD=ON -DUSE_SHA1=HTTPS -DUSE_BUNDLED_ZLIB=ON
113+
SKIP_SSH_TESTS: true
114+
SKIP_NEGOTIATE_TESTS: true
115+
- # Windows amd64 mingw
116+
os: windows-2019
117+
setup-script: mingw
118+
env:
119+
ARCH: amd64
120+
CMAKE_GENERATOR: MinGW Makefiles
121+
CMAKE_OPTIONS: -DDEPRECATE_HARD=ON
122+
BUILD_TEMP: D:\Temp
123+
BUILD_PATH: D:\Temp\mingw64\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Program Files (x86)\CMake\bin
124+
SKIP_SSH_TESTS: true
125+
SKIP_NEGOTIATE_TESTS: true
126+
- # Windows x86 mingw
127+
os: windows-2019
128+
setup-script: mingw
129+
env:
130+
ARCH: x86
131+
CMAKE_GENERATOR: MinGW Makefiles
132+
CMAKE_OPTIONS: -DDEPRECATE_HARD=ON
133+
BUILD_TEMP: D:\Temp
134+
BUILD_PATH: D:\Temp\mingw32\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Program Files (x86)\CMake\bin
135+
SKIP_SSH_TESTS: true
136+
SKIP_NEGOTIATE_TESTS: true
137+
fail-fast: false
138+
env: ${{ matrix.platform.env }}
139+
runs-on: ${{ matrix.platform.os }}
140+
steps:
141+
- name: Check out repository
142+
uses: actions/checkout@v2
143+
with:
144+
fetch-depth: 0
145+
- name: Set up build environment
146+
run: azure-pipelines/setup-${{ matrix.platform.setup-script }}.sh
147+
shell: bash
148+
if: matrix.platform.setup-script != ''
149+
- name: Download container
150+
run: azure-pipelines/getcontainer.sh ${{ env.docker-config-path }}/${{ matrix.platform.image }}
151+
env:
152+
DOCKER_REGISTRY: ${{ env.docker-registry }}
153+
GITHUB_TOKEN: ${{ secrets.github_token }}
154+
if: matrix.platform.image != ''
155+
- name: Create container
156+
run: docker build -t ${{ env.docker-registry-container-sha }} -f ${{ matrix.platform.image }} .
157+
working-directory: ${{ env.docker-config-path }}
158+
if: matrix.platform.image != '' && env.docker-container-exists != 'true'
159+
- name: Build and test
160+
run: |
161+
export GITTEST_NEGOTIATE_PASSWORD="${{ secrets.GITTEST_NEGOTIATE_PASSWORD }}"
162+
163+
if [ -n "${{ matrix.platform.image }}" ]; then
164+
docker run -v $(pwd):/home/libgit2/source -w /home/libgit2/source -e CC -e CMAKE_GENERATOR -e CMAKE_OPTIONS -e PKG_CONFIG_PATH -e GITTEST_NEGOTIATE_PASSWORD -e SKIP_SSH_TESTS -e SKIP_NEGOTIATE_TESTS ${{ env.docker-registry-container-sha }} /bin/bash -c "mkdir build && cd build && ../azure-pipelines/build.sh && ../azure-pipelines/test.sh"
165+
else
166+
mkdir build && cd build
167+
../azure-pipelines/build.sh
168+
../azure-pipelines/test.sh
169+
fi
170+
shell: bash
171+
172+
# Generate documentation using docurium. We'll upload the documentation
173+
# as a build artifact so that it can be reviewed as part of a pull
174+
# request or in a forked build. For CI builds in the main repository's
175+
# master branch, we'll push the gh-pages branch back up so that it is
176+
# published to our documentation site.
177+
documentation:
178+
name: Generate documentation
179+
needs: [build_containers]
180+
runs-on: ubuntu-latest
181+
steps:
182+
- name: Check out repository
183+
uses: actions/checkout@v2
184+
with:
185+
fetch-depth: 0
186+
- name: Generate documentation
187+
run: |
188+
git config user.name 'Documentation Generation'
189+
git config user.email 'libgit2@users.noreply.github.com'
190+
git branch gh-pages origin/gh-pages
191+
docker login https://${{ env.docker-registry }} -u ${{ github.actor }} -p ${{ github.token }}
192+
docker run --rm -v $(pwd):/home/libgit2/source -w /home/libgit2/source ${{ env.docker-registry }}/${{ github.repository }}/docurium:latest cm doc api.docurium
193+
git checkout gh-pages
194+
zip --exclude .git/\* --exclude .gitignore --exclude .gitattributes -r api-documentation.zip .
195+
- uses: actions/upload-artifact@v2
196+
name: Upload artifact
197+
with:
198+
name: api-documentation
199+
path: api-documentation.zip
200+
- name: Push documentation branch
201+
run: git push origin gh-pages
202+
if: github.event_name == 'push' && github.repository == 'libgit2/libgit2'

azure-pipelines/build.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ BUILD_PATH=${BUILD_PATH:=$PATH}
1313
CMAKE=$(which cmake)
1414
CMAKE_GENERATOR=${CMAKE_GENERATOR:-Unix Makefiles}
1515

16+
if [[ "$(uname -s)" == MINGW* ]]; then
17+
BUILD_PATH=$(cygpath "$BUILD_PATH")
18+
fi
19+
1620
indent() { sed "s/^/ /"; }
1721

1822
echo "Source directory: ${SOURCE_DIR}"

azure-pipelines/getcontainer.sh

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
DOCKERFILE_PATH=$1
6+
7+
if [ "${DOCKERFILE_PATH}" = "" ]; then
8+
echo "usage: $0 dockerfile"
9+
exit 1
10+
fi
11+
12+
if [ "${DOCKER_REGISTRY}" = "" ]; then
13+
echo "DOCKER_REGISTRY environment variable is unset."
14+
echo "Not running inside GitHub Actions or misconfigured?"
15+
exit 1
16+
fi
17+
18+
DOCKER_CONTAINER="${GITHUB_REPOSITORY}/$(basename ${DOCKERFILE_PATH})"
19+
DOCKER_REGISTRY_CONTAINER="${DOCKER_REGISTRY}/${DOCKER_CONTAINER}"
20+
21+
echo "::set-env name=docker-container::${DOCKER_CONTAINER}"
22+
echo "::set-env name=docker-registry-container::${DOCKER_REGISTRY_CONTAINER}"
23+
24+
# Identify the last git commit that touched the Dockerfiles
25+
# Use this as a hash to identify the resulting docker containers
26+
DOCKER_SHA=$(git log -1 --pretty=format:"%h" -- "${DOCKERFILE_PATH}")
27+
echo "::set-env name=docker-sha::${DOCKER_SHA}"
28+
29+
DOCKER_REGISTRY_CONTAINER_SHA="${DOCKER_REGISTRY_CONTAINER}:${DOCKER_SHA}"
30+
31+
echo "::set-env name=docker-registry-container-sha::${DOCKER_REGISTRY_CONTAINER_SHA}"
32+
echo "::set-env name=docker-registry-container-latest::${DOCKER_REGISTRY_CONTAINER}:latest"
33+
34+
exists="true"
35+
docker login https://${DOCKER_REGISTRY} -u ${GITHUB_ACTOR} -p ${GITHUB_TOKEN} || exists="false"
36+
37+
if [ "${exists}" != "false" ]; then
38+
docker pull ${DOCKER_REGISTRY_CONTAINER_SHA} || exists="false"
39+
fi
40+
41+
if [ "${exists}" = "true" ]; then
42+
echo "::set-env name=docker-container-exists::true"
43+
else
44+
echo "::set-env name=docker-container-exists::false"
45+
fi

azure-pipelines/setup-mingw.sh

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,22 @@ echo "##########################################################################
44
echo "## Downloading mingw"
55
echo "##############################################################################"
66

7+
BUILD_TEMP=${BUILD_TEMP:=$TEMP}
8+
BUILD_TEMP=$(cygpath $BUILD_TEMP)
9+
710
case "$ARCH" in
811
amd64)
912
MINGW_URI="https://bintray.com/libgit2/build-dependencies/download_file?file_path=mingw-w64-x86_64-8.1.0-release-win32-seh-rt_v6-rev0.zip";;
1013
x86)
1114
MINGW_URI="https://bintray.com/libgit2/build-dependencies/download_file?file_path=mingw-w64-i686-8.1.0-release-win32-sjlj-rt_v6-rev0.zip";;
1215
esac
1316

14-
curl -s -L "$MINGW_URI" -o "$TEMP"/mingw-"$ARCH".zip
15-
unzip -q "$TEMP"/mingw-"$ARCH".zip -d "$TEMP"
17+
if [ -z "$MINGW_URI" ]; then
18+
echo "No URL"
19+
exit 1
20+
fi
21+
22+
mkdir -p "$BUILD_TEMP"
23+
24+
curl -s -L "$MINGW_URI" -o "$BUILD_TEMP"/mingw-"$ARCH".zip
25+
unzip -q "$BUILD_TEMP"/mingw-"$ARCH".zip -d "$BUILD_TEMP"

0 commit comments

Comments
 (0)