Merge branch 'master' into davkal/babel-7

This commit is contained in:
Torkel Ödegaard
2018-11-23 13:44:59 +01:00
426 changed files with 20781 additions and 3787 deletions
-43
View File
@@ -1,43 +0,0 @@
FROM centos:6.6
RUN yum install -y yum-plugin-ovl initscripts curl tar gcc libc6-dev git gcc-c++ openssl-devel && \
yum install -y g++ make automake autoconf curl-devel zlib-devel httpd-devel apr-devel apr-util-devel sqlite-devel && \
yum install -y wget yum-utils bzip2 bzip2-devel && \
yum install -y fontconfig freetype freetype-devel fontconfig-devel libstdc++ && \
yum install -y rpm-build patch readline readline-devel libtool bison lzma && \
yum install -y which tar
# Install RUBY 1.9.3
# install necessary utilities
# RUN yum install -y which tar
RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 && \
curl -sSl https://raw.githubusercontent.com/rvm/rvm/master/binscripts/rvm-installer | bash -s stable && \
source /etc/profile.d/rvm.sh && \
/bin/bash -l -c "rvm requirements" && \
/bin/bash -l -c "rvm install 2.1.9" && \
/bin/bash -l -c "rvm use 2.1.9 --default"
# install nodejs
RUN curl --silent --location https://rpm.nodesource.com/setup_6.x | bash - && \
yum install -y nodejs --nogpgcheck
ENV GOLANG_VERSION 1.11
RUN wget https://dl.yarnpkg.com/rpm/yarn.repo -O /etc/yum.repos.d/yarn.repo && \
yum install -y yarn --nogpgcheck && \
wget https://storage.googleapis.com/golang/go${GOLANG_VERSION}.linux-amd64.tar.gz && \
tar -C /usr/local -xzf go${GOLANG_VERSION}.linux-amd64.tar.gz
ENV PATH /usr/local/go/bin:$PATH
RUN mkdir -p /go/src /go/bin && chmod -R 777 /go
ENV GOPATH /go
ENV PATH /go/bin:$PATH
ADD ./build.sh /tmp/
WORKDIR /tmp/
CMD ["./build.sh"]
+3 -5
View File
@@ -22,19 +22,17 @@ echo "current dir: $(pwd)"
if [ "$CIRCLE_TAG" != "" ]; then
echo "Building releases from tag $CIRCLE_TAG"
OPT="-includeBuildNumber=false ${EXTRA_OPTS}"
OPT="-includeBuildId=false ${EXTRA_OPTS}"
else
echo "Building incremental build for $CIRCLE_BRANCH"
OPT="-buildNumber=${CIRCLE_BUILD_NUM} ${EXTRA_OPTS}"
OPT="-buildId=${CIRCLE_WORKFLOW_ID} ${EXTRA_OPTS}"
fi
echo "Build arguments: $OPT"
go run build.go -goarch armv7 -cc ${CCARMV7} ${OPT} build
go run build.go -goarch arm64 -cc ${CCARM64} ${OPT} build
# MacOS build is broken atm. See Issue #13763
#go run build.go -goos darwin -cc ${CCOSX64} ${OPT} build
go run build.go -goos darwin -cc ${CCOSX64} ${OPT} build
go run build.go -goos windows -cc ${CCWIN64} ${OPT} build
CC=${CCX64} go run build.go ${OPT} build
+2 -2
View File
@@ -18,10 +18,10 @@ echo "current dir: $(pwd)"
if [ "$CIRCLE_TAG" != "" ]; then
echo "Building releases from tag $CIRCLE_TAG"
OPT="-includeBuildNumber=false ${EXTRA_OPTS}"
OPT="-includeBuildId=false ${EXTRA_OPTS}"
else
echo "Building incremental build for $CIRCLE_BRANCH"
OPT="-buildNumber=${CIRCLE_BUILD_NUM} ${EXTRA_OPTS}"
OPT="-buildId=${CIRCLE_WORKFLOW_ID} ${EXTRA_OPTS}"
fi
echo "Build arguments: $OPT"
-17
View File
@@ -1,17 +0,0 @@
#!/bin/bash
docker info && docker version
mkdir -p ~/docker
echo "Circle branch: ${CIRCLE_BRANCH}"
echo "Circle tag: ${CIRCLE_TAG}"
# try to load docker container from cache
if [[ -e ~/docker/centos.tar ]]; then
docker load -i ~/docker/centos.tar;
else
docker build --rm=false --tag "grafana/buildcontainer" ./scripts/build/
# save docker container so we don't have to recreate it next run
docker save grafana/buildcontainer > ~/docker/centos.tar;
fi
+5
View File
@@ -0,0 +1,5 @@
FROM circleci/python:2.7-stretch
RUN sudo pip install awscli && \
curl https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-222.0.0-linux-x86_64.tar.gz | \
sudo tar xvzf - -C /opt
+7
View File
@@ -0,0 +1,7 @@
#!/bin/bash
_version="1.0.0"
_tag="grafana/grafana-ci-deploy:${_version}"
docker build -t $_tag .
docker push $_tag
-14
View File
@@ -1,14 +0,0 @@
#!/bin/bash
mkdir -p dist
echo "Circle branch: ${CIRCLE_BRANCH}"
echo "Circle tag: ${CIRCLE_TAG}"
docker run -i -t --name gfbuild \
-v $(pwd):/go/src/github.com/grafana/grafana \
-e "CIRCLE_BRANCH=${CIRCLE_BRANCH}" \
-e "CIRCLE_TAG=${CIRCLE_TAG}" \
-e "CIRCLE_BUILD_NUM=${CIRCLE_BUILD_NUM}" \
grafana/buildcontainer
sudo chown -R ${USER:=$(/usr/bin/id -run)}:$USER dist
+7 -5
View File
@@ -1,14 +1,16 @@
#/bin/sh
#!/bin/sh
# no relation to publish.go
# Right now we hack this in into the publish script.
EXTRA_OPTS="$@"
# Right now we hack this in into the publish script.
# Eventually we might want to keep a list of all previous releases somewhere.
_releaseNoteUrl="https://community.grafana.com/t/release-notes-v5-3-x/10244"
_whatsNewUrl="http://docs.grafana.org/guides/whats-new-in-v5-3/"
_releaseNoteUrl="https://community.grafana.com/t/release-notes-v5-4-x/12215"
_whatsNewUrl="http://docs.grafana.org/guides/whats-new-in-v5-4/"
./scripts/build/release_publisher/release_publisher \
--wn ${_whatsNewUrl} \
--rn ${_releaseNoteUrl} \
--version ${CIRCLE_TAG} \
--apikey ${GRAFANA_COM_API_KEY}
--apikey ${GRAFANA_COM_API_KEY} ${EXTRA_OPTS}
@@ -0,0 +1,70 @@
package main
import (
"fmt"
"io/ioutil"
"net/http"
"strings"
"time"
)
type releaseFromExternalContent struct {
getter urlGetter
rawVersion string
artifactConfigurations []buildArtifact
}
func (re releaseFromExternalContent) prepareRelease(baseArchiveUrl, whatsNewUrl string, releaseNotesUrl string, nightly bool) (*release, error) {
version := re.rawVersion[1:]
beta := strings.Contains(version, "beta")
var rt ReleaseType
if beta {
rt = BETA
} else if nightly {
rt = NIGHTLY
} else {
rt = STABLE
}
builds := []build{}
for _, ba := range re.artifactConfigurations {
sha256, err := re.getter.getContents(fmt.Sprintf("%s.sha256", ba.getUrl(baseArchiveUrl, version, rt)))
if err != nil {
return nil, err
}
builds = append(builds, newBuild(baseArchiveUrl, ba, version, rt, sha256))
}
r := release{
Version: version,
ReleaseDate: time.Now().UTC(),
Stable: rt.stable(),
Beta: rt.beta(),
Nightly: rt.nightly(),
WhatsNewUrl: whatsNewUrl,
ReleaseNotesUrl: releaseNotesUrl,
Builds: builds,
}
return &r, nil
}
type urlGetter interface {
getContents(url string) (string, error)
}
type getHttpContents struct{}
func (getHttpContents) getContents(url string) (string, error) {
response, err := http.Get(url)
if err != nil {
return "", err
}
defer response.Body.Close()
all, err := ioutil.ReadAll(response.Body)
if err != nil {
return "", err
}
return string(all), nil
}
@@ -0,0 +1,94 @@
package main
import (
"fmt"
"github.com/pkg/errors"
"io/ioutil"
"log"
"os"
"path/filepath"
"regexp"
"strings"
"time"
)
type releaseLocalSources struct {
path string
artifactConfigurations []buildArtifact
}
func (r releaseLocalSources) prepareRelease(baseArchiveUrl, whatsNewUrl string, releaseNotesUrl string, nightly bool) (*release, error) {
if !nightly {
return nil, errors.New("Local releases only supported for nightly builds.")
}
buildData := r.findBuilds(baseArchiveUrl)
rel := release{
Version: buildData.version,
ReleaseDate: time.Now().UTC(),
Stable: false,
Beta: false,
Nightly: nightly,
WhatsNewUrl: whatsNewUrl,
ReleaseNotesUrl: releaseNotesUrl,
Builds: buildData.builds,
}
return &rel, nil
}
type buildData struct {
version string
builds []build
}
func (r releaseLocalSources) findBuilds(baseArchiveUrl string) buildData {
data := buildData{}
filepath.Walk(r.path, createBuildWalker(r.path, &data, r.artifactConfigurations, baseArchiveUrl))
return data
}
func createBuildWalker(path string, data *buildData, archiveTypes []buildArtifact, baseArchiveUrl string) func(path string, f os.FileInfo, err error) error {
return func(path string, f os.FileInfo, err error) error {
if err != nil {
log.Printf("error: %v", err)
}
if f.Name() == path || strings.HasSuffix(f.Name(), ".sha256") {
return nil
}
for _, archive := range archiveTypes {
if strings.HasSuffix(f.Name(), archive.urlPostfix) {
shaBytes, err := ioutil.ReadFile(path + ".sha256")
if err != nil {
log.Fatalf("Failed to read sha256 file %v", err)
}
version, err := grabVersion(f.Name(), archive.urlPostfix)
if err != nil {
log.Println(err)
continue
}
data.version = version
data.builds = append(data.builds, build{
Os: archive.os,
Url: archive.getUrl(baseArchiveUrl, version, NIGHTLY),
Sha256: string(shaBytes),
Arch: archive.arch,
})
return nil
}
}
return nil
}
}
func grabVersion(name string, suffix string) (string, error) {
match := regexp.MustCompile(fmt.Sprintf(`grafana(-enterprise)?[-_](.*)%s`, suffix)).FindSubmatch([]byte(name))
if len(match) > 0 {
return string(match[2]), nil
}
return "", errors.New("No version found.")
}
+69 -6
View File
@@ -7,13 +7,14 @@ import (
"os"
)
var baseUri string = "https://grafana.com/api"
func main() {
var version string
var whatsNewUrl string
var releaseNotesUrl string
var dryRun bool
var enterprise bool
var fromLocal bool
var nightly bool
var apiKey string
flag.StringVar(&version, "version", "", "Grafana version (ex: --version v5.2.0-beta1)")
@@ -21,20 +22,82 @@ func main() {
flag.StringVar(&releaseNotesUrl, "rn", "", "Grafana version (ex: --rn https://community.grafana.com/t/release-notes-v5-2-x/7894)")
flag.StringVar(&apiKey, "apikey", "", "Grafana.com API key (ex: --apikey ABCDEF)")
flag.BoolVar(&dryRun, "dry-run", false, "--dry-run")
flag.BoolVar(&enterprise, "enterprise", false, "--enterprise")
flag.BoolVar(&fromLocal, "from-local", false, "--from-local (builds will be tagged as nightly)")
flag.Parse()
nightly = fromLocal
if len(os.Args) == 1 {
fmt.Println("Usage: go run publisher.go main.go --version <v> --wn <what's new url> --rn <release notes url> --apikey <api key> --dry-run false")
fmt.Println("example: go run publisher.go main.go --version v5.2.0-beta2 --wn http://docs.grafana.org/guides/whats-new-in-v5-2/ --rn https://community.grafana.com/t/release-notes-v5-2-x/7894 --apikey ASDF123 --dry-run true")
fmt.Println("Usage: go run publisher.go main.go --version <v> --wn <what's new url> --rn <release notes url> --apikey <api key> --dry-run false --enterprise false --nightly false")
fmt.Println("example: go run publisher.go main.go --version v5.2.0-beta2 --wn http://docs.grafana.org/guides/whats-new-in-v5-2/ --rn https://community.grafana.com/t/release-notes-v5-2-x/7894 --apikey ASDF123 --dry-run --enterprise")
os.Exit(1)
}
if dryRun {
log.Println("Dry-run has been enabled.")
}
var baseUrl string
var builder releaseBuilder
var product string
p := publisher{apiKey: apiKey}
if err := p.doRelease(version, whatsNewUrl, releaseNotesUrl, dryRun); err != nil {
archiveProviderRoot := "https://s3-us-west-2.amazonaws.com"
buildArtifacts := completeBuildArtifactConfigurations
if enterprise {
product = "grafana-enterprise"
baseUrl = createBaseUrl(archiveProviderRoot, "grafana-enterprise-releases", product, nightly)
var err error
buildArtifacts, err = filterBuildArtifacts([]artifactFilter{
{os: "deb", arch: "amd64"},
{os: "rhel", arch: "amd64"},
{os: "linux", arch: "amd64"},
{os: "win", arch: "amd64"},
})
if err != nil {
log.Fatalf("Could not filter to the selected build artifacts, err=%v", err)
}
} else {
product = "grafana"
baseUrl = createBaseUrl(archiveProviderRoot, "grafana-releases", product, nightly)
}
if fromLocal {
path, _ := os.Getwd()
builder = releaseLocalSources{
path: path,
artifactConfigurations: buildArtifacts,
}
} else {
builder = releaseFromExternalContent{
getter: getHttpContents{},
rawVersion: version,
artifactConfigurations: buildArtifacts,
}
}
p := publisher{
apiKey: apiKey,
apiUri: "https://grafana.com/api",
product: product,
dryRun: dryRun,
enterprise: enterprise,
baseArchiveUrl: baseUrl,
builder: builder,
}
if err := p.doRelease(whatsNewUrl, releaseNotesUrl, nightly); err != nil {
log.Fatalf("error: %v", err)
}
}
func createBaseUrl(root string, bucketName string, product string, nightly bool) string {
var subPath string
if nightly {
subPath = "master"
} else {
subPath = "release"
}
return fmt.Sprintf("%s/%s/%s/%s", root, bucketName, subPath, product)
}
+80 -79
View File
@@ -4,6 +4,7 @@ import (
"bytes"
"encoding/json"
"fmt"
"github.com/pkg/errors"
"io/ioutil"
"log"
"net/http"
@@ -12,53 +13,47 @@ import (
)
type publisher struct {
apiKey string
apiKey string
apiUri string
product string
dryRun bool
enterprise bool
baseArchiveUrl string
builder releaseBuilder
}
func (p *publisher) doRelease(version string, whatsNewUrl string, releaseNotesUrl string, dryRun bool) error {
currentRelease, err := newRelease(version, whatsNewUrl, releaseNotesUrl, buildArtifactConfigurations, getHttpContents{})
type releaseBuilder interface {
prepareRelease(baseArchiveUrl, whatsNewUrl string, releaseNotesUrl string, nightly bool) (*release, error)
}
func (p *publisher) doRelease(whatsNewUrl string, releaseNotesUrl string, nightly bool) error {
currentRelease, err := p.builder.prepareRelease(p.baseArchiveUrl, whatsNewUrl, releaseNotesUrl, nightly)
if err != nil {
return err
}
if dryRun {
relJson, err := json.Marshal(currentRelease)
if err != nil {
return err
}
log.Println(string(relJson))
for _, b := range currentRelease.Builds {
artifactJson, err := json.Marshal(b)
if err != nil {
return err
}
log.Println(string(artifactJson))
}
} else {
if err := p.postRelease(currentRelease); err != nil {
return err
}
if err := p.postRelease(currentRelease); err != nil {
return err
}
return nil
}
func (p *publisher) postRelease(r *release) error {
err := p.postRequest("/grafana/versions", r, fmt.Sprintf("Create Release %s", r.Version))
err := p.postRequest("/versions", r, fmt.Sprintf("Create Release %s", r.Version))
if err != nil {
return err
}
err = p.postRequest("/grafana/versions/"+r.Version, r, fmt.Sprintf("Update Release %s", r.Version))
err = p.postRequest("/versions/"+r.Version, r, fmt.Sprintf("Update Release %s", r.Version))
if err != nil {
return err
}
for _, b := range r.Builds {
err = p.postRequest(fmt.Sprintf("/grafana/versions/%s/packages", r.Version), b, fmt.Sprintf("Create Build %s %s", b.Os, b.Arch))
err = p.postRequest(fmt.Sprintf("/versions/%s/packages", r.Version), b, fmt.Sprintf("Create Build %s %s", b.Os, b.Arch))
if err != nil {
return err
}
err = p.postRequest(fmt.Sprintf("/grafana/versions/%s/packages/%s/%s", r.Version, b.Arch, b.Os), b, fmt.Sprintf("Update Build %s %s", b.Os, b.Arch))
err = p.postRequest(fmt.Sprintf("/versions/%s/packages/%s/%s", r.Version, b.Arch, b.Os), b, fmt.Sprintf("Update Build %s %s", b.Os, b.Arch))
if err != nil {
return err
}
@@ -67,7 +62,25 @@ func (p *publisher) postRelease(r *release) error {
return nil
}
const baseArhiveUrl = "https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana"
type ReleaseType int
const (
STABLE ReleaseType = iota + 1
BETA
NIGHTLY
)
func (rt ReleaseType) beta() bool {
return rt == BETA
}
func (rt ReleaseType) stable() bool {
return rt == STABLE
}
func (rt ReleaseType) nightly() bool {
return rt == NIGHTLY
}
type buildArtifact struct {
os string
@@ -75,7 +88,7 @@ type buildArtifact struct {
urlPostfix string
}
func (t buildArtifact) getUrl(version string, isBeta bool) string {
func (t buildArtifact) getUrl(baseArchiveUrl, version string, releaseType ReleaseType) string {
prefix := "-"
rhelReleaseExtra := ""
@@ -83,15 +96,15 @@ func (t buildArtifact) getUrl(version string, isBeta bool) string {
prefix = "_"
}
if !isBeta && t.os == "rhel" {
if releaseType.stable() && t.os == "rhel" {
rhelReleaseExtra = "-1"
}
url := strings.Join([]string{baseArhiveUrl, prefix, version, rhelReleaseExtra, t.urlPostfix}, "")
url := strings.Join([]string{baseArchiveUrl, prefix, version, rhelReleaseExtra, t.urlPostfix}, "")
return url
}
var buildArtifactConfigurations = []buildArtifact{
var completeBuildArtifactConfigurations = []buildArtifact{
{
os: "deb",
arch: "arm64",
@@ -149,48 +162,57 @@ var buildArtifactConfigurations = []buildArtifact{
},
}
func newRelease(rawVersion string, whatsNewUrl string, releaseNotesUrl string, artifactConfigurations []buildArtifact, getter urlGetter) (*release, error) {
version := rawVersion[1:]
now := time.Now()
isBeta := strings.Contains(version, "beta")
builds := []build{}
for _, ba := range artifactConfigurations {
sha256, err := getter.getContents(fmt.Sprintf("%s.sha256", ba.getUrl(version, isBeta)))
if err != nil {
return nil, err
}
builds = append(builds, newBuild(ba, version, isBeta, sha256))
}
r := release{
Version: version,
ReleaseDate: time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local),
Stable: !isBeta,
Beta: isBeta,
Nightly: false,
WhatsNewUrl: whatsNewUrl,
ReleaseNotesUrl: releaseNotesUrl,
Builds: builds,
}
return &r, nil
type artifactFilter struct {
os string
arch string
}
func newBuild(ba buildArtifact, version string, isBeta bool, sha256 string) build {
func filterBuildArtifacts(filters []artifactFilter) ([]buildArtifact, error) {
var artifacts []buildArtifact
for _, f := range filters {
matched := false
for _, a := range completeBuildArtifactConfigurations {
if f.os == a.os && f.arch == a.arch {
artifacts = append(artifacts, a)
matched = true
break
}
}
if !matched {
return nil, errors.New(fmt.Sprintf("No buildArtifact for os=%v, arch=%v", f.os, f.arch))
}
}
return artifacts, nil
}
func newBuild(baseArchiveUrl string, ba buildArtifact, version string, rt ReleaseType, sha256 string) build {
return build{
Os: ba.os,
Url: ba.getUrl(version, isBeta),
Url: ba.getUrl(baseArchiveUrl, version, rt),
Sha256: sha256,
Arch: ba.arch,
}
}
func (p *publisher) apiUrl(url string) string {
return fmt.Sprintf("%s/%s%s", p.apiUri, p.product, url)
}
func (p *publisher) postRequest(url string, obj interface{}, desc string) error {
jsonBytes, err := json.Marshal(obj)
if err != nil {
return err
}
req, err := http.NewRequest(http.MethodPost, baseUri+url, bytes.NewReader(jsonBytes))
if p.dryRun {
log.Println(fmt.Sprintf("POST to %s:", p.apiUrl(url)))
log.Println(string(jsonBytes))
return nil
}
req, err := http.NewRequest(http.MethodPost, p.apiUrl(url), bytes.NewReader(jsonBytes))
if err != nil {
return err
}
@@ -243,24 +265,3 @@ type build struct {
Sha256 string `json:"sha256"`
Arch string `json:"arch"`
}
type urlGetter interface {
getContents(url string) (string, error)
}
type getHttpContents struct{}
func (getHttpContents) getContents(url string) (string, error) {
response, err := http.Get(url)
if err != nil {
return "", err
}
defer response.Body.Close()
all, err := ioutil.ReadAll(response.Body)
if err != nil {
return "", err
}
return string(all), nil
}
+182 -25
View File
@@ -2,37 +2,100 @@ package main
import "testing"
func TestNewRelease(t *testing.T) {
versionIn := "v5.2.0-beta1"
expectedVersion := "5.2.0-beta1"
whatsNewUrl := "https://whatsnews.foo/"
relNotesUrl := "https://relnotes.foo/"
expectedArch := "amd64"
expectedOs := "linux"
buildArtifacts := []buildArtifact{{expectedOs, expectedArch, ".linux-amd64.tar.gz"}}
func TestPreparingReleaseFromRemote(t *testing.T) {
rel, _ := newRelease(versionIn, whatsNewUrl, relNotesUrl, buildArtifacts, mockHttpGetter{})
if !rel.Beta || rel.Stable {
t.Errorf("%s should have been tagged as beta (not stable), but wasn't .", versionIn)
cases := []struct {
version string
expectedVersion string
whatsNewUrl string
relNotesUrl string
nightly bool
expectedBeta bool
expectedStable bool
expectedArch string
expectedOs string
expectedUrl string
baseArchiveUrl string
buildArtifacts []buildArtifact
}{
{
version: "v5.2.0-beta1",
expectedVersion: "5.2.0-beta1",
whatsNewUrl: "https://whatsnews.foo/",
relNotesUrl: "https://relnotes.foo/",
nightly: false,
expectedBeta: true,
expectedStable: false,
expectedArch: "amd64",
expectedOs: "linux",
expectedUrl: "https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.2.0-beta1.linux-amd64.tar.gz",
baseArchiveUrl: "https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana",
buildArtifacts: []buildArtifact{{"linux", "amd64", ".linux-amd64.tar.gz"}},
},
{
version: "v5.2.3",
expectedVersion: "5.2.3",
whatsNewUrl: "https://whatsnews.foo/",
relNotesUrl: "https://relnotes.foo/",
nightly: false,
expectedBeta: false,
expectedStable: true,
expectedArch: "amd64",
expectedOs: "rhel",
expectedUrl: "https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.2.3-1.x86_64.rpm",
baseArchiveUrl: "https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana",
buildArtifacts: []buildArtifact{{"rhel", "amd64", ".x86_64.rpm"}},
},
{
version: "v5.4.0-pre1asdf",
expectedVersion: "5.4.0-pre1asdf",
whatsNewUrl: "https://whatsnews.foo/",
relNotesUrl: "https://relnotes.foo/",
nightly: true,
expectedBeta: false,
expectedStable: false,
expectedArch: "amd64",
expectedOs: "rhel",
expectedUrl: "https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.4.0-pre1asdf.x86_64.rpm",
baseArchiveUrl: "https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana",
buildArtifacts: []buildArtifact{{"rhel", "amd64", ".x86_64.rpm"}},
},
}
if rel.Version != expectedVersion {
t.Errorf("Expected version to be %s, but it was %s.", expectedVersion, rel.Version)
}
for _, test := range cases {
builder := releaseFromExternalContent{
getter: mockHttpGetter{},
rawVersion: test.version,
artifactConfigurations: test.buildArtifacts,
}
expectedBuilds := len(buildArtifacts)
if len(rel.Builds) != expectedBuilds {
t.Errorf("Expected %v builds, but got %v.", expectedBuilds, len(rel.Builds))
}
rel, _ := builder.prepareRelease(test.baseArchiveUrl, test.whatsNewUrl, test.relNotesUrl, test.nightly)
build := rel.Builds[0]
if build.Arch != expectedArch {
t.Errorf("Expected arch to be %v, but it was %v", expectedArch, build.Arch)
}
if rel.Beta != test.expectedBeta || rel.Stable != test.expectedStable {
t.Errorf("%s should have been tagged as beta=%v, stable=%v.", test.version, test.expectedBeta, test.expectedStable)
}
if build.Os != expectedOs {
t.Errorf("Expected arch to be %v, but it was %v", expectedOs, build.Os)
if rel.Version != test.expectedVersion {
t.Errorf("Expected version to be %s, but it was %s.", test.expectedVersion, rel.Version)
}
expectedBuilds := len(test.buildArtifacts)
if len(rel.Builds) != expectedBuilds {
t.Errorf("Expected %v builds, but got %v.", expectedBuilds, len(rel.Builds))
}
build := rel.Builds[0]
if build.Arch != test.expectedArch {
t.Errorf("Expected arch to be %v, but it was %v", test.expectedArch, build.Arch)
}
if build.Os != test.expectedOs {
t.Errorf("Expected os to be %v, but it was %v", test.expectedOs, build.Os)
}
if build.Url != test.expectedUrl {
t.Errorf("Expected url to be %v, but it was %v", test.expectedUrl, build.Url)
}
}
}
@@ -41,3 +104,97 @@ type mockHttpGetter struct{}
func (mockHttpGetter) getContents(url string) (string, error) {
return url, nil
}
func TestPreparingReleaseFromLocal(t *testing.T) {
whatsNewUrl := "https://whatsnews.foo/"
relNotesUrl := "https://relnotes.foo/"
expectedVersion := "5.4.0-123pre1"
expectedBuilds := 4
var builder releaseBuilder
testDataPath := "testdata"
builder = releaseLocalSources{
path: testDataPath,
artifactConfigurations: completeBuildArtifactConfigurations,
}
relAll, _ := builder.prepareRelease("https://s3-us-west-2.amazonaws.com/grafana-enterprise-releases/master/grafana-enterprise", whatsNewUrl, relNotesUrl, true)
if relAll.Stable || !relAll.Nightly {
t.Error("Expected a nightly release but wasn't.")
}
if relAll.ReleaseNotesUrl != relNotesUrl {
t.Errorf("expected releaseNotesUrl to be %s, but it was %s", relNotesUrl, relAll.ReleaseNotesUrl)
}
if relAll.WhatsNewUrl != whatsNewUrl {
t.Errorf("expected whatsNewUrl to be %s, but it was %s", whatsNewUrl, relAll.WhatsNewUrl)
}
if relAll.Beta {
t.Errorf("Expected release to be nightly, not beta.")
}
if relAll.Version != expectedVersion {
t.Errorf("Expected version=%s, but got=%s", expectedVersion, relAll.Version)
}
if len(relAll.Builds) != expectedBuilds {
t.Errorf("Expected %v builds, but was %v", expectedBuilds, len(relAll.Builds))
}
expectedArch := "amd64"
expectedOs := "win"
builder = releaseLocalSources{
path: testDataPath,
artifactConfigurations: []buildArtifact{{
os: expectedOs,
arch: expectedArch,
urlPostfix: ".windows-amd64.zip",
}},
}
relOne, _ := builder.prepareRelease("https://s3-us-west-2.amazonaws.com/grafana-enterprise-releases/master/grafana-enterprise", whatsNewUrl, relNotesUrl, true)
if len(relOne.Builds) != 1 {
t.Errorf("Expected 1 artifact, but was %v", len(relOne.Builds))
}
build := relOne.Builds[0]
if build.Arch != expectedArch {
t.Fatalf("Expected arch to be %s, but was %s", expectedArch, build.Arch)
}
if build.Os != expectedOs {
t.Fatalf("Expected os to be %s, but was %s", expectedOs, build.Os)
}
_, err := builder.prepareRelease("", "", "", false)
if err == nil {
t.Error("Error was nil, but expected an error as the local releaser only supports nightly builds.")
}
}
func TestFilterBuildArtifacts(t *testing.T) {
buildArtifacts, _ := filterBuildArtifacts([]artifactFilter{
{os: "deb", arch: "amd64"},
{os: "rhel", arch: "amd64"},
{os: "linux", arch: "amd64"},
{os: "win", arch: "amd64"},
})
if len(buildArtifacts) != 4 {
t.Errorf("Expected 4 build artifacts after filtering, but was %v", len(buildArtifacts))
}
_, err := filterBuildArtifacts([]artifactFilter{
{os: "foobar", arch: "amd64"},
})
if err == nil {
t.Errorf("Expected an error as a we tried to filter on a nonexiststant os.")
}
}
@@ -0,0 +1 @@
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
@@ -0,0 +1 @@
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
@@ -0,0 +1 @@
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
@@ -0,0 +1 @@
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+2 -2
View File
@@ -17,8 +17,8 @@ module.exports = function (grunt) {
grunt.registerTask('precommit', [
'sasslint',
'exec:tslint',
'exec:tsc',
'newer:exec:tslint',
'newer:exec:tsc',
'no-only-tests'
]);
+8 -2
View File
@@ -2,8 +2,14 @@ module.exports = function (config, grunt) {
'use strict';
return {
tslint: 'node ./node_modules/tslint/lib/tslintCli.js -c tslint.json --project ./tsconfig.json',
tsc: 'yarn tsc --noEmit',
tslint: {
command: 'node ./node_modules/tslint/lib/tslintCli.js -c tslint.json --project ./tsconfig.json',
src: ['public/app/**/*.ts*'],
},
tsc: {
command: 'yarn tsc --noEmit',
src: ['public/app/**/*.ts*'],
},
jest: 'node ./node_modules/jest-cli/bin/jest.js --maxWorkers 2',
webpack: 'node ./node_modules/webpack/bin/webpack.js --config scripts/webpack/webpack.prod.js',
};
+2 -2
View File
@@ -16,7 +16,7 @@ module.exports = {
publicPath: "public/build/",
},
resolve: {
extensions: ['.ts', '.tsx', '.es6', '.js', '.json'],
extensions: ['.ts', '.tsx', '.es6', '.js', '.json', '.svg'],
alias: {
},
modules: [
@@ -47,7 +47,7 @@ module.exports = {
},
{
test: /\.html$/,
exclude: /index\.template.html/,
exclude: /(index|error)\-template\.html/,
use: [
{ loader: 'ngtemplate-loader?relativeTo=' + (path.resolve(__dirname, '../../public')) + '&prefix=public' },
{
+7 -2
View File
@@ -80,11 +80,16 @@ module.exports = merge(common, {
plugins: [
new CleanWebpackPlugin('../../public/build', { allowExternal: true }),
new MiniCssExtractPlugin({
filename: "grafana.[name].css"
filename: "grafana.[name].[hash].css"
}),
new HtmlWebpackPlugin({
filename: path.resolve(__dirname, '../../public/views/error.html'),
template: path.resolve(__dirname, '../../public/views/error-template.html'),
inject: false,
}),
new HtmlWebpackPlugin({
filename: path.resolve(__dirname, '../../public/views/index.html'),
template: path.resolve(__dirname, '../../public/views/index.template.html'),
template: path.resolve(__dirname, '../../public/views/index-template.html'),
inject: 'body',
chunks: ['manifest', 'vendor', 'app'],
}),
+1 -1
View File
@@ -93,7 +93,7 @@ module.exports = merge(common, {
new CleanWebpackPlugin('../public/build', { allowExternal: true }),
new HtmlWebpackPlugin({
filename: path.resolve(__dirname, '../../public/views/index.html'),
template: path.resolve(__dirname, '../../public/views/index.template.html'),
template: path.resolve(__dirname, '../../public/views/index-template.html'),
inject: 'body',
alwaysWriteToDisk: true
}),
+7 -2
View File
@@ -71,12 +71,17 @@ module.exports = merge(common, {
plugins: [
new MiniCssExtractPlugin({
filename: "grafana.[name].css"
filename: "grafana.[name].[hash].css"
}),
new ngAnnotatePlugin(),
new HtmlWebpackPlugin({
filename: path.resolve(__dirname, '../../public/views/error.html'),
template: path.resolve(__dirname, '../../public/views/error-template.html'),
inject: false,
}),
new HtmlWebpackPlugin({
filename: path.resolve(__dirname, '../../public/views/index.html'),
template: path.resolve(__dirname, '../../public/views/index.template.html'),
template: path.resolve(__dirname, '../../public/views/index-template.html'),
inject: 'body',
chunks: ['vendor', 'app'],
}),