feat(build-system): add support for AppVeyor CI (#2449)

pull/1755/merge
Steven Kang 2018-12-07 16:19:58 +13:00 committed by Anthony Lapenna
parent 2541f4daea
commit 65979709e9
12 changed files with 343 additions and 27 deletions

44
appveyor-ci.yml Normal file
View File

@ -0,0 +1,44 @@
version: 1.0.{build}
image:
- Visual Studio 2017
- Ubuntu
environment:
matrix:
- ARCH: amd64
- ARCH: arm
- ARCH: arm64
- ARCH: ppc64le
- ARCH: s390x
DOCKER_USER:
secure: JapmC7j5F0mY3j/MVzU+Cw==
DOCKER_PASS:
secure: QGlCLNWzPD0HL8ipkohVic45/yU3bVOdjn0IiV6NnSQ=
matrix:
exclude:
- image: Visual Studio 2017
ARCH: arm
- image: Visual Studio 2017
ARCH: arm64
- image: Visual Studio 2017
ARCH: ppc64le
- image: Visual Studio 2017
ARCH: s390x
branches:
except:
- master
stack:
- node 9, go 1.10
install:
- yarn install
- npm install -g rebase-docker-image
init:
- sh: export IMAGE=linux
- cmd: SET IMAGE=windows
- ps: >-
if (!(Test-Path ~/.docker)) { mkdir ~/.docker };
Set-Content -Value '{ "experimental": "enabled" }' -Path ~/.docker/config.json -Encoding Ascii
build_script:
- sh: yarn grunt release:$IMAGE:$ARCH
- cmd: yarn grunt release:%IMAGE%:%ARCH%
- sh: sudo bash build/ci-linux.sh $IMAGE $ARCH $DOCKER_USER $DOCKER_PASS $APPVEYOR_REPO_BRANCH $APPVEYOR_PULL_REQUEST_NUMBER
- cmd: powershell -Command "& .\\build\\ci-windows.ps1"

61
appveyor-release.yml Normal file
View File

@ -0,0 +1,61 @@
version: 1.0.{build}
image:
- Visual Studio 2017
- Ubuntu
environment:
matrix:
- ARCH: amd64
- ARCH: arm
- ARCH: arm64
- ARCH: ppc64le
- ARCH: s390x
DOCKER_USER:
secure: JapmC7j5F0mY3j/MVzU+Cw==
DOCKER_PASS:
secure: QGlCLNWzPD0HL8ipkohVic45/yU3bVOdjn0IiV6NnSQ=
PORTAINER_VERSION: "1.19.2"
matrix:
exclude:
- image: Visual Studio 2017
ARCH: arm
- image: Visual Studio 2017
ARCH: arm64
- image: Visual Studio 2017
ARCH: ppc64le
- image: Visual Studio 2017
ARCH: s390x
branches:
only:
- master
stack: node 9, go 1.10
artifacts:
- path: 'portainer-$(PORTAINER_VERSION)-$(IMAGE)-$(ARCH).tar.gz'
type: file
- path: 'portainer-$(PORTAINER_VERSION)-$(IMAGE)-$(ARCH)-checksum.txt'
type: file
install:
- yarn install
- npm install -g rebase-docker-image
init:
- sh: export IMAGE=linux
- cmd: SET IMAGE=windows
- ps: >-
if (!(Test-Path ~/.docker)) { mkdir ~/.docker }
Set-Content -Value '{ "experimental": "enabled" }' -Path ~/.docker/config.json -Encoding Ascii
build_script:
- sh: yarn grunt release:$IMAGE:$ARCH
- cmd: yarn grunt release:%IMAGE%:%ARCH%
- sh: sudo bash build/release-linux.sh $IMAGE $ARCH $PORTAINER_VERSION $DOCKER_USER $DOCKER_PASS
- cmd: powershell -Command "& .\\build\\release-windows.ps1"
test: off
deploy:
release: Release $(PORTAINER_VERSION)
description: ''
provider: GitHub
auth_token:
secure: BRYVGj94QlFBCMoO8yhSu+AGqKNV1+03LJEFrNUTRzo5erXfUHUIi/rgztnxfSGW
artifact: /portainer-$(PORTAINER_VERSION)-$(IMAGE)-$(ARCH).*/
draft: true
prerelease: false
on:
branch: master

24
build/build_binary.ps1 Normal file
View File

@ -0,0 +1,24 @@
param (
[string]$platform,
[string]$arch
)
$ErrorActionPreference = "Stop";
$binary = "portainer.exe"
$project_path = (Get-ITEM -Path env:APPVEYOR_BUILD_FOLDER).Value
Set-Item env:GOPATH "$project_path\api"
New-Item -Name dist -Path "$project_path" -ItemType Directory | Out-Null
New-Item -Name portainer -Path "$project_path\api\src\github.com\" -ItemType Directory | Out-Null
Copy-Item -Path "$project_path\api" -Destination "$project_path\api\src\github.com\portainer" -Recurse -Force -ErrorAction:SilentlyContinue
Rename-Item -Path "$project_path\api\src\github.com\portainer\api" -NewName "portainer" -ErrorAction:SilentlyContinue
Set-Location -Path "$project_path\api\cmd\portainer"
C:\go\bin\go.exe get -t -d -v ./...
C:\go\bin\go.exe build -v
Move-Item -Path "$project_path\api\cmd\portainer\$($binary)" -Destination "$project_path\dist"

14
build/build_binary.sh Executable file
View File

@ -0,0 +1,14 @@
export GOPATH="$APPVEYOR_BUILD_FOLDER/api"
binary="portainer"
mkdir -p dist
mkdir -p api/src/github.com/portainer/
cp -R api/ api/src/github.com/portainer/portainer/
cd 'api/cmd/portainer'
go get -t -d -v ./...
GOOS=$1 GOARCH=$2 CGO_ENABLED=0 go build -a --installsuffix cgo --ldflags '-s'
mv "$APPVEYOR_BUILD_FOLDER/api/cmd/portainer/$binary" "$APPVEYOR_BUILD_FOLDER/dist/portainer"

View File

@ -1,10 +0,0 @@
#!/usr/bin/env sh
binary="portainer-$1-$2"
mkdir -p dist
docker run --rm -tv "$(pwd)/api:/src" -e BUILD_GOOS="$1" -e BUILD_GOARCH="$2" portainer/golang-builder:cross-platform /src/cmd/portainer
mv "api/cmd/portainer/$binary" dist/
#sha256sum "dist/$binary" > portainer-checksum.txt

28
build/ci-linux.sh Normal file
View File

@ -0,0 +1,28 @@
IMAGE="$1"
ARCH="$2"
DOCKER_USER="$3"
DOCKER_PASS="$4"
APPVEYOR_REPO_BRANCH="$5"
APPVEYOR_PULL_REQUEST_NUMBER="$6"
if [ "${APPVEYOR_PULL_REQUEST_NUMBER}" ]; then
tag="pr${APPVEYOR_PULL_REQUEST_NUMBER}-$IMAGE-$ARCH"
manifest="pr${APPVEYOR_PULL_REQUEST_NUMBER}"
else
tag="${APPVEYOR_REPO_BRANCH}-$IMAGE-$ARCH"
manifest="${APPVEYOR_REPO_BRANCH}"
fi
docker build -t "portainer/portainer:$tag" -f build/linux/Dockerfile .
docker login -u "${DOCKER_USER}" -p "${DOCKER_PASS}"
docker push "portainer/portainer:$tag"
if [ "${2}" == 'amd64' ] ; then
docker -D manifest create "portainer/portainer:$manifest" \
"portainer/portainer:$manifest-linux-amd64" \
"portainer/portainer:$manifest-windows-amd64" \
"portainer/portainer:$manifest-windows1709-amd64" \
"portainer/portainer:$manifest-windows1803-amd64"
docker manifest push "portainer/portainer:$manifest"
fi

36
build/ci-windows.ps1 Normal file
View File

@ -0,0 +1,36 @@
$ErrorActionPreference = "Stop";
$pull_request_number = $ENV:APPVEYOR_PULL_REQUEST_NUMBER
$branch_name = $ENV:APPVEYOR_REPO_BRANCH
$os = (Get-Item ENV:IMAGE).Value
$arch = (Get-Item ENV:ARCH).Value
if ($pull_request_number) {
$tag = "pr$($pull_request_number)-$($os)-$($arch)"
$tag_1709 = "pr$($pull_request_number)-$($os)1709-$($arch)"
$tag_1803 = "pr$($pull_request_number)-$($os)1803-$($arch)"
} else {
$tag = "$($branch_name)-$($os)-$($arch)"
$tag_1709 = "$($branch_name)-$($os)1709-$($arch)"
$tag_1803 = "$($branch_name)-$($os)1803-$($arch)"
}
docker build `
-t portainer/portainer:$tag `
-f build\windows2016\nanoserver\Dockerfile .
docker login `
-u "$((Get-Item ENV:DOCKER_USER).Value)" `
-p "$((Get-Item ENV:DOCKER_PASS).Value)"
docker push portainer/portainer:$tag
rebase-docker-image `
portainer/portainer:$tag `
-t portainer/portainer:$tag_1709 `
-b microsoft/nanoserver:1709
rebase-docker-image `
portainer/portainer:$tag `
-t portainer/portainer:$tag_1803 `
-b microsoft/nanoserver:1803

View File

@ -0,0 +1,13 @@
param (
[string]$docker_version
)
$ErrorActionPreference = "Stop";
New-Item -Path "docker-binary" -ItemType Directory | Out-Null
$download_folder = "docker-binary"
Invoke-WebRequest -O "$($download_folder)/docker-binaries.zip" "https://download.docker.com/win/static/stable/x86_64/docker-$($docker_version).zip"
Expand-Archive -Path "$($download_folder)/docker-binaries.zip" -DestinationPath "$($download_folder)"
Move-Item -Path "$($download_folder)/docker/docker.exe" -Destination "dist"

View File

@ -19,4 +19,4 @@ else
mv "${DOWNLOAD_FOLDER}/docker/docker" dist/
fi
exit 0
exit 0

45
build/release-linux.sh Normal file
View File

@ -0,0 +1,45 @@
IMAGE="$1"
ARCH="$2"
PORTAINER_VERSION="$3"
DOCKER_USER="$4"
DOCKER_PASS="$5"
mkdir -pv portainer
cp -r dist/* portainer
tar cvpfz "portainer-$PORTAINER_VERSION-$IMAGE-$ARCH.tar.gz" portainer
sha256sum --tag "portainer-$PORTAINER_VERSION-$IMAGE-$ARCH.tar.gz" > "portainer-$PORTAINER_VERSION-$IMAGE-$ARCH-checksum.txt"
tag="$IMAGE-$ARCH"
docker build -t "portainer/portainer:$IMAGE-$ARCH-$PORTAINER_VERSION" -f build/linux/Dockerfile .
docker tag "portainer/portainer:$IMAGE-$ARCH-$PORTAINER_VERSION" "portainer/portainer:$IMAGE-$ARCH"
docker login -u "$DOCKER_USER" -p "$DOCKER_PASS"
docker push "portainer/portainer:$IMAGE-$ARCH-$PORTAINER_VERSION"
docker push "portainer/portainer:$IMAGE-$ARCH"
if [ "${2}" == 's390x' ] ; then
docker -D manifest create "portainer/portainer:latest" \
"portainer/portainer:linux-amd64" \
"portainer/portainer:linux-arm" \
"portainer/portainer:linux-arm64" \
"portainer/portainer:linux-ppc64le" \
"portainer/portainer:linux-s390x" \
"portainer/portainer:windows-amd64" \
"portainer/portainer:windows1709-amd64" \
"portainer/portainer:windows1803-amd64"
docker manifest push "portainer/portainer:latest"
docker -D manifest create "portainer/portainer:${PORTAINER_VERSION}" \
"portainer/portainer:linux-amd64-${PORTAINER_VERSION}" \
"portainer/portainer:linux-arm-${PORTAINER_VERSION}" \
"portainer/portainer:linux-arm64-${PORTAINER_VERSION}" \
"portainer/portainer:linux-ppc64le-${PORTAINER_VERSION}" \
"portainer/portainer:linux-s390x-${PORTAINER_VERSION}" \
"portainer/portainer:windows-amd64-${PORTAINER_VERSION}" \
"portainer/portainer:windows1709-amd64-${PORTAINER_VERSION}" \
"portainer/portainer:windows1803-amd64-${PORTAINER_VERSION}"
docker manifest push "portainer/portainer:${PORTAINER_VERSION}"
fi

41
build/release-windows.ps1 Normal file
View File

@ -0,0 +1,41 @@
$ErrorActionPreference = "Stop";
$binary = "portainer-$((Get-Item ENV:PORTAINER_VERSION).Value)-$((Get-Item ENV:IMAGE).Value)-$((Get-Item ENV:ARCH).Value).tar.gz"
New-Item -Path portainer -ItemType Directory | Out-Null
Copy-Item -Path dist\* -Destination portainer -Recurse
tar cvpfz $binary portainer
(Get-FileHash $binary).Hash > "portainer-$((Get-Item ENV:PORTAINER_VERSION).Value)-$((Get-Item ENV:IMAGE).Value)-$((Get-Item ENV:ARCH).Value)-checksum.txt"
docker build `
-t portainer/portainer:$((Get-Item ENV:IMAGE).Value)-$((Get-Item ENV:ARCH).Value)-$((Get-Item ENV:PORTAINER_VERSION).Value) `
-f build\windows2016\nanoserver\Dockerfile .
docker tag portainer/portainer:$((Get-Item ENV:IMAGE).Value)-$((Get-Item ENV:ARCH).Value)-$((Get-Item ENV:PORTAINER_VERSION).Value) portainer/portainer:$((Get-Item ENV:IMAGE).Value)-$((Get-Item ENV:ARCH).Value)
docker login `
-u "$((Get-Item ENV:DOCKER_USER).Value)" `
-p "$((Get-Item ENV:DOCKER_PASS).Value)"
docker push portainer/portainer:$((Get-Item ENV:IMAGE).Value)-$((Get-Item ENV:ARCH).Value)-$((Get-Item ENV:PORTAINER_VERSION).Value)
docker push portainer/portainer:$((Get-Item ENV:IMAGE).Value)-$((Get-Item ENV:ARCH).Value)
rebase-docker-image `
portainer/portainer:$((Get-Item ENV:IMAGE).Value)-$((Get-Item ENV:ARCH).Value) `
-t portainer/portainer:$((Get-Item ENV:IMAGE).Value)1709-$((Get-Item ENV:ARCH).Value)-$((Get-Item ENV:PORTAINER_VERSION).Value) `
-b microsoft/nanoserver:1709
rebase-docker-image `
portainer/portainer:$((Get-Item ENV:IMAGE).Value)-$((Get-Item ENV:ARCH).Value) `
-t portainer/portainer:$((Get-Item ENV:IMAGE).Value)1709-$((Get-Item ENV:ARCH).Value) `
-b microsoft/nanoserver:1709
rebase-docker-image `
portainer/portainer:$((Get-Item ENV:IMAGE).Value)-$((Get-Item ENV:ARCH).Value) `
-t portainer/portainer:$((Get-Item ENV:IMAGE).Value)1803-$((Get-Item ENV:ARCH).Value)-$((Get-Item ENV:PORTAINER_VERSION).Value) `
-b microsoft/nanoserver:1803
rebase-docker-image `
portainer/portainer:$((Get-Item ENV:IMAGE).Value)-$((Get-Item ENV:ARCH).Value) `
-t portainer/portainer:$((Get-Item ENV:IMAGE).Value)1803-$((Get-Item ENV:ARCH).Value) `
-b microsoft/nanoserver:1803

View File

@ -259,14 +259,24 @@ gruntfile_cfg.replace = {
};
function shell_buildBinary(p, a) {
var binfile = 'dist/portainer-' + p + '-' + a;
return [
'if [ -f ' + ((p === 'windows') ? binfile + '.exe' : binfile) + ' ]; then',
'echo "Portainer binary exists";',
'else',
'build/build_in_container.sh ' + p + ' ' + a + ';',
'fi'
].join(' ');
var binfile = 'portainer-'+p+'-'+a;
if (p === "linux") {
return [
'if [ -f '+(binfile)+' ]; then',
'echo "Portainer binary exists";',
'else',
'build/build_binary.sh ' + p + ' ' + a + ';',
'fi'
].join (' ')
} else {
return [
'powershell -Command "& {if (Get-Item -Path '+(binfile+'.exe')+' -ErrorAction:SilentlyContinue) {',
'Write-Host "Portainer binary exists"',
'} else {',
'& ".\\build\\build_binary.ps1" -platform '+ p +' -arch '+ a +'',
'}}"'
].join(' ')
}
}
function shell_run(arch) {
@ -281,14 +291,24 @@ function shell_downloadDockerBinary(p, a) {
var as = { 'amd64': 'x86_64', 'arm': 'armhf', 'arm64': 'aarch64' };
var ip = ((ps[p] === undefined) ? p : ps[p]);
var ia = ((as[a] === undefined) ? a : as[a]);
var binaryVersion = ((p === 'windows' ? '<%= shippedDockerVersionWindows %>' : '<%= shippedDockerVersion %>'));
return [
'if [ -f ' + ((p === 'windows') ? 'dist/docker.exe' : 'dist/docker') + ' ]; then',
'echo "Docker binary exists";',
'else',
'build/download_docker_binary.sh ' + ip + ' ' + ia + ' ' + binaryVersion + ';',
'fi'
].join(' ');
var binaryVersion = (( p === 'windows' ? '<%= shippedDockerVersionWindows %>' : '<%= shippedDockerVersion %>' ));
if (p === "linux") {
return [
'if [ -f '+('dist/docker')+' ]; then',
'echo "Docker binary exists";',
'else',
'build/download_docker_binary.sh ' + ip + ' ' + ia + ' ' + binaryVersion + ';',
'fi'
].join (' ')
} else {
return [
'powershell -Command "& {if (Get-Item -Path '+('dist/docker.exe')+' -ErrorAction:SilentlyContinue) {',
'Write-Host "Docker binary exists"',
'} else {',
'& ".\\build\\download_docker_binary.ps1" -docker_version '+ binaryVersion +'',
'}}"'
].join(' ')
}
}
gruntfile_cfg.shell = {