Release binaries on S3 bucket

Create a new release job to release the binaries for each commit,
master, and tag created into their respective bucket.

The s3 bucket information are stored inside of **Settings > CI/CD >
Variables**
parent 5c5661ad
......@@ -4,6 +4,7 @@ stages:
- prepare
- validate
- build
- release
variables:
USE_CONTAINER: "true"
......@@ -51,6 +52,42 @@ variables:
<<: *build_base
script: make build-x
.release:
image: ${CI_IMAGE}
stage: release
tags:
- release
.release_development:
only:
refs:
- merge_requests
.release_beta:
only:
refs:
- [email protected]/ci-cd/custom-executors/autoscaler
- /\Av[0-9]+\.[0-9]+\.[0-9]+-gitlab\.[0-9]+-rc[0-9]+\Z/@gitlab-org/ci-cd/docker-machine
.release_stable:
only:
refs:
- /\Av[0-9]+\.[0-9]+\.[0-9]+-gitlab\.[0-9]+\Z/@gitlab-org/ci-cd/docker-machine
.release_S3:
dependencies:
- linux amd64
- linux arm
- linux arm64
- windows amd64
- darwin amd64
variables:
S3_URL: s3://${S3_BUCKET}/${CI_COMMIT_REF_NAME}
script:
- ./.gitlab/ci/scripts/release_s3.sh
environment:
url: https://${S3_BUCKET}.s3.amazonaws.com/${CI_COMMIT_REF_NAME}/index.html
prepare CI image:
extends:
- .docker_in_docker
......@@ -73,3 +110,42 @@ windows amd64: *build_x
linux arm: *build_x
linux arm64: *build_x
release development S3:
extends:
- .release
- .release_development
- .release_S3
environment:
name: development/S3/${CI_COMMIT_REF_NAME}
on_stop: stop release development S3
stop release development S3:
dependencies: []
extends:
- .release
- .release_development
- .release_S3
variables:
GIT_STRATEGY: none
script:
- aws s3 rm ${S3_URL} --recursive
when: manual
environment:
name: development/S3/${CI_COMMIT_REF_NAME}
action: stop
release beta S3:
extends:
- .release
- .release_beta
- .release_S3
environment:
name: beta/S3
release stable S3:
extends:
- .release
- .release_stable
- .release_S3
environment:
name: stable/S3
package main
import (
"bytes"
"crypto/sha256"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
"text/template"
"time"
)
type entry struct {
FullPath string
RelativePath string
Checksum string
SizeMb float64
}
type release struct {
Name string
Project string
SourceURL string
Revision string
Ref string
CreatedAt string
Files []entry
}
var (
indexFile string
checksumsFile string
)
func main() {
if len(os.Args) < 5 {
fmt.Printf("Usage: %s scan_dir version ref revision\n", os.Args[0])
os.Exit(1)
}
scanDir := strings.Trim(os.Args[1], "/")
version := os.Args[2]
ref := os.Args[3]
revision := os.Args[4]
indexFile = filepath.Join(scanDir, "index.html")
checksumsFile = filepath.Join(scanDir, "release.sha256")
files, err := filepath.Glob(fmt.Sprintf("%s/*", scanDir))
if err != nil {
log.Fatalf("Failed to scan dir %q for files: %v", scanDir, err)
}
entries := make([]entry, 0)
for _, file := range files {
entries = append(entries, getFileEntry(scanDir, file))
}
checksumFileEntry := createChecksumsFile(scanDir, checksumsFile, entries)
entries = append(entries, checksumFileEntry)
releaseInfo := release{
Name: version,
Project: "GitLab Runner - Custom Executor's autoscaling driver",
SourceURL: fmt.Sprintf("%s/tree/%s", os.Getenv("CI_PROJECT_URL"), ref),
Revision: revision,
Ref: ref,
CreatedAt: time.Now().Format(time.RFC3339),
Files: entries,
}
tpl, err := template.New("release").Parse(indexTemplate)
if err != nil {
log.Fatalf("Failed to parse the template: %v", err)
}
buf := new(bytes.Buffer)
err = tpl.Execute(buf, releaseInfo)
if err != nil {
log.Fatalf("Failed to parse the template: %v", err)
}
err = ioutil.WriteFile(indexFile, buf.Bytes(), 0600)
if err != nil {
log.Fatalf("Failed to write to the index file %q: %v", indexFile, err)
}
}
func getFileEntry(scanDir string, file string) entry {
f, err := os.Open(file)
if err != nil {
log.Fatalf("Failed to open the file %q: %v", file, err)
}
defer f.Close()
hasher := sha256.New()
_, err = io.Copy(hasher, f)
if err != nil {
log.Fatalf("Failed to copy file's %q content to the SHA256 hash calculator: %v", file, err)
}
fileInfo, err := os.Stat(file)
if err != nil {
log.Fatalf("Failed to stat the file %q: %v", file, err)
}
return entry{
FullPath: file,
RelativePath: strings.Replace(file, fmt.Sprintf("%s/", scanDir), "", -1),
Checksum: fmt.Sprintf("%x", hasher.Sum(nil)),
SizeMb: float64(fileInfo.Size()) / 1048576,
}
}
func createChecksumsFile(scanDir string, file string, entries []entry) entry {
f, err := os.Create(file)
if err != nil {
log.Fatalf("Failed to open the file %q: %v", file, err)
}
defer f.Close()
for _, fileEntry := range entries {
if fileEntry.FullPath == indexFile || fileEntry.FullPath == checksumsFile {
continue
}
_, err := fmt.Fprintf(f, "%s\t%s\n", fileEntry.Checksum, fileEntry.RelativePath)
if err != nil {
log.Fatalf("Failed to write to file %q: %v", file, err)
}
}
return getFileEntry(scanDir, file)
}
var indexTemplate = `
{{ $title := (print .Project " :: " .Name) }}
<html>
<head>
<meta charset="utf-8/">
<title>{{ $title }}</title>
<style type="text/css">
body {font-family: monospace; font-size: 14px; margin: 40px; padding: 0;}
h1 {border-bottom: 1px solid #aaa; padding: 10px;}
p {font-size: 0.85em; margin: 5px 10px;}
p span {display: inline-block; font-weight: bold; width: 100px;}
p a {color: #000; font-weight: bold; text-decoration: none;}
p a:hover {text-decoration: underline;}
ul {background: #eee; border: 1px solid #aaa; border-radius: 3px; box-shadow: 0 0 5px #aaa inset; list-style-type: none; margin: 10px 0; padding: 10px;}
li {margin: 5px 0; padding: 5px; font-size: 12px;}
li:hover {background: #dedede;}
.file_name {display: inline-block; font-weight: bold; width: calc(100% - 610px);}
.file_name a {color: #000; display: inline-block; text-decoration: none; width: calc(100% - 10px);}
.file_checksum {display: inline-block; text-align: right; width: 500px;}
.file_size {display: inline-block; text-align: right; width: 90px;}
</style>
</head>
<body>
<h1>{{ $title }}</h1>
<p><span>Sources:</span> <a href="{{ .SourceURL }}" target="_blank">{{ .SourceURL }}</a></p>
<p><span>Revision:</span> {{ .Revision }}</p>
<p><span>Ref:</span> {{ .Ref }}</p>
<p><span>Created at:</span> {{ .CreatedAt }}</p>
<ul>
{{ range $_, $file := .Files }}
<li>
<span class="file_name"><a href="./{{ $file.RelativePath }}">{{ $file.RelativePath }}</a></span>
<span class="file_checksum">{{ $file.Checksum }}</span>
<span class="file_size">{{ printf "%2.2f" $file.SizeMb }} MiB</span>
</li>
{{ end }}
</ul>
</body>
</html>
`
#!/usr/bin/env bash
set -eo pipefail
tag=${1:-$CI_COMMIT_TAG}
if [[ -z "${tag}" ]]; then
echo -e "\033[0;31m****** gitlab publishing disabled ******\033[0m"
echo -e "usage:\n\t$0 tag"
exit 0
fi
if [[ -z "${DEPLOY_TOKEN}" ]]; then
echo -e "\033[0;31m****** Missing DEPLOY_TOKEN, cannot release ******\033[0m"
exit 0
fi
api=${CI_API_V4_URL:-https://gitlab.com/api/v4}
projectID=${CI_PROJECT_ID:-1254421}
projectUrl=${CI_PROJECT_URL:-https://gitlab.com/gitlab-org/ci-cd/docker-machine}
changelogUrl="${projectUrl}/blob/${tag}/CHANGELOG.md"
s3=${CI_ENVIRONMENT_URL/\/index.html/}
release=$(cat <<EOS
{
"name": "${tag}",
"tag_name": "${tag}",
"description": "See [the changelog](${changelogUrl}) :rocket:",
"assets": {
"links": [
{ "name": "linux amd64", "url": "$s3/docker-machine" },
{ "name": "macOS amd64", "url": "$s3/docker-machine-Darwin-x86_64" },
{ "name": "Windows amd64", "url": "$s3/docker-machine-Windows-x86_64.exe" },
{ "name": "others", "url": "$s3/index.html" }
]
}
}
EOS
)
curl -f \
--header 'Content-Type: application/json' \
--header "PRIVATE-TOKEN: ${DEPLOY_TOKEN}" \
--data "${release}" \
--request POST \
"${api}/projects/${projectID}/releases"
#!/usr/bin/env bash
set -eo pipefail
VERSION="$(./.gitlab/ci/scripts/version.sh 2>/dev/null || echo 'dev')"
# Generate Index page.
go run ./.gitlab/ci/scripts/generate-index-file/main.go bin/ ${VERSION} ${CI_COMMIT_REF_NAME} ${CI_COMMIT_SHA}
echo "Generated Index page"
aws s3 sync bin ${S3_URL} --acl public-read
# Copy the binaries to the latest directory.
LATEST_STABLE_TAG=$(git -c versionsort.prereleaseSuffix="-rc" tag -l "v*.*.*" --sort=-v:refname | awk '!/rc/' | head -n 1)
if [ $(git describe --exact-match --match ${LATEST_STABLE_TAG} >/dev/null 2>&1) ]; then
aws s3 sync bin s3://${S3_BUCKET}/latest --acl public-read
fi
# Add assets to release page
bash ./.gitlab/ci/scripts/gitlab_release.sh
#!/usr/bin/env bash
set -eo pipefail
version=$((cat version/version.go | grep 'Version =' | sed -n 's/^.*\([0-9]\+\.[0-9]\+\.[0-9]\+-gitlab\.[0-9]\+\).*$/\1/p') || echo dev2 | sed -e 's/^v//g')
exact_tag=$(git describe --exact-match --tags --always 2>/dev/null | sed -e 's/^v//g' || echo "")
if [[ $(echo ${exact_tag} | grep -E "^[0-9]+\.[0-9]+\.[0-9]+-gitlab\.[0-9]+(-rc[0-9]+)?$") ]]; then
echo ${exact_tag}
exit 0
fi
pre_release_info=$(git describe --always --long | sed -r "s/v[0-9\.]+(-rc[0-9]+)?-gitlab\.[0-9]+-//")
echo "${version}-beta-${pre_release_info}"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment