diff --git a/.github/workflows/continuous_delivery.yaml b/.github/workflows/continuous_delivery.yaml index 58ccdaf18879fc64b8616c467b1be9a8e7cd19b7..1897561d8f113999c40f964129c256f82ebd8569 100644 --- a/.github/workflows/continuous_delivery.yaml +++ b/.github/workflows/continuous_delivery.yaml @@ -30,10 +30,10 @@ jobs: steps: - name: Setup uses: actions/setup-go@v2 - with: - go-version: '1.14' + - name: Checkout uses: actions/checkout@v2 + - name: Lint run: make lint @@ -43,14 +43,16 @@ jobs: steps: - name: Setup uses: actions/setup-go@v2 - with: - go-version: '1.14' + - name: Checkout uses: actions/checkout@v2 + - name: Build run: make build + - name: Test run: make testci + - name: Code coverage uses: codecov/codecov-action@v1 with: @@ -62,18 +64,20 @@ jobs: strategy: matrix: go_version: - - '1.11' - - '1.12' - '1.13' + - '1.14' steps: - name: Setup uses: actions/setup-go@v2 with: go-version: ${{matrix.go_version}} + - name: Checkout uses: actions/checkout@v2 + - name: Build run: make build + - name: Test run: make test diff --git a/Makefile b/Makefile index f9c9c5a4bec5d101aefeff433753a7fa5bb564db..cdb9979804e3c7342b4ded2bd061a2e38f1a9e59 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: clean deploy deps image imagepush lint run stagedeploy test testci testcover +.PHONY: clean deploy deps gcloud-auth image imagepush lint run stagedeploy test testci testcover # The version that will be used in docker tags (e.g. to push a # go-httpbin:latest image use `make imagepush VERSION=latest)` @@ -8,6 +8,9 @@ VERSION ?= $(shell git rev-parse --short HEAD) GCLOUD_PROJECT ?= httpbingo GCLOUD_ACCOUNT ?= mccutchen@gmail.com +# Run gcloud in a container to avoid needing to install the SDK locally +GCLOUD_COMMAND ?= ./bin/gcloud + # Built binaries will be placed here DIST_PATH ?= dist @@ -44,7 +47,7 @@ clean: rm -rf $(DIST_PATH) $(COVERAGE_PATH) $(GENERATED_ASSETS_PATH): $(TOOL_GOBINDATA) static/* - $(TOOL_GOBINDATA) -o $(GENERATED_ASSETS_PATH) -pkg=assets -prefix=static static + $(TOOL_GOBINDATA) -o $(GENERATED_ASSETS_PATH) -pkg=assets -prefix=static -modtime=1601471052 static # reformat generated code gofmt -s -w $(GENERATED_ASSETS_PATH) # dumb hack to make generate code lint correctly @@ -59,11 +62,13 @@ $(GENERATED_ASSETS_PATH): $(TOOL_GOBINDATA) static/* test: go test $(TEST_ARGS) ./... + # Test command to run for continuous integration, which includes code coverage # based on codecov.io's documentation: # https://github.com/codecov/example-go/blob/b85638743b972bd0bd2af63421fe513c6f968930/README.md -testci: +testci: build go test $(TEST_ARGS) $(COVERAGE_ARGS) ./... + git diff --exit-code testcover: testci go tool cover -html=$(COVERAGE_PATH) @@ -78,11 +83,14 @@ lint: $(TOOL_GOLINT) $(TOOL_STATICCHECK) # ============================================================================= # deploy & run locally # ============================================================================= -deploy: build - gcloud --account=$(GCLOUD_ACCOUNT) app deploy --quiet --project=$(GCLOUD_PROJECT) --version=$(VERSION) --promote +deploy: build gcloud-auth + $(GCLOUD_COMMAND) --account=$(GCLOUD_ACCOUNT) app deploy --quiet --project=$(GCLOUD_PROJECT) --version=$(VERSION) --promote + +stagedeploy: build gcloud-auth + $(GCLOUD_COMMAND) --account=$(GCLOUD_ACCOUNT) app deploy --quiet --project=$(GCLOUD_PROJECT) --version=$(VERSION) --no-promote -stagedeploy: build - gcloud --account=$(GCLOUD_ACCOUNT) app deploy --quiet --project=$(GCLOUD_PROJECT) --version=$(VERSION) --no-promote +gcloud-auth: + @$(GCLOUD_COMMAND) auth list | grep '^\*' | grep -q $(GCLOUD_ACCOUNT) || $(GCLOUD_COMMAND) auth login $(GCLOUD_ACCOUNT) run: build $(DIST_PATH)/go-httpbin diff --git a/bin/gcloud b/bin/gcloud new file mode 100755 index 0000000000000000000000000000000000000000..0c3b367c638c88291a946e58816a14552dfd490d --- /dev/null +++ b/bin/gcloud @@ -0,0 +1,15 @@ +#!/bin/bash +# +# A wrapper that executes the gcloud CLI in a docker container, to avoid +# requiring a local installation. +# +# Adapted from this helpful blog post: +# https://blog.scottlowe.org/2018/09/13/running-gcloud-cli-in-a-docker-container/ + +exec docker run \ + --rm \ + -ti \ + --workdir /code \ + -v $PWD:/code \ + -v $HOME/.config/gcloud:/root/.config/gcloud \ + google/cloud-sdk gcloud $* diff --git a/httpbin/assets/assets.go b/httpbin/assets/assets.go index 13e50688f8befbbc5e7f20ce678f306a0de3d308..df339f651620b8fbb917a64b340cd9c2cfa8e5e4 100644 --- a/httpbin/assets/assets.go +++ b/httpbin/assets/assets.go @@ -93,7 +93,7 @@ func formsPostHTML() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "forms-post.html", size: 1398, mode: os.FileMode(0644), modTime: time.Unix(1538761140, 0)} + info := bindataFileInfo{name: "forms-post.html", size: 1398, mode: os.FileMode(0644), modTime: time.Unix(1601471052, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb5, 0xe8, 0x65, 0x54, 0x38, 0x49, 0xec, 0xc3, 0xb0, 0xc3, 0x68, 0x14, 0x55, 0xcf, 0xe6, 0x3b, 0x9d, 0xb5, 0x55, 0xee, 0xc4, 0xe7, 0xf6, 0x20, 0x70, 0x5, 0x9a, 0x8f, 0x32, 0xc4, 0x66, 0x23}} return a, nil } @@ -113,7 +113,7 @@ func imageJpeg() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "image.jpeg", size: 35588, mode: os.FileMode(0644), modTime: time.Unix(1498336884, 0)} + info := bindataFileInfo{name: "image.jpeg", size: 35588, mode: os.FileMode(0644), modTime: time.Unix(1601471052, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc0, 0x28, 0xd7, 0xaa, 0x15, 0xe8, 0x51, 0xb0, 0xee, 0xfb, 0x31, 0x63, 0x8a, 0x18, 0x56, 0x49, 0x8a, 0x23, 0x7f, 0xaf, 0x18, 0x29, 0x5, 0x8, 0x32, 0xd3, 0xb9, 0xb1, 0x9f, 0x9a, 0xb7, 0x5f}} return a, nil } @@ -133,7 +133,7 @@ func imagePng() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "image.png", size: 8090, mode: os.FileMode(0644), modTime: time.Unix(1498336884, 0)} + info := bindataFileInfo{name: "image.png", size: 8090, mode: os.FileMode(0644), modTime: time.Unix(1601471052, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x54, 0x1a, 0x1e, 0xf5, 0x37, 0x3b, 0xe3, 0xdc, 0x49, 0xfc, 0x54, 0x2f, 0xd9, 0xa6, 0x51, 0x77, 0xb6, 0x64, 0xae, 0xc0, 0x1c, 0x8d, 0x86, 0x8, 0xf9, 0x9e, 0x6e, 0xc9, 0x55, 0x77, 0xd8, 0xc1}} return a, nil } @@ -153,7 +153,7 @@ func imageSvg() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "image.svg", size: 8984, mode: os.FileMode(0644), modTime: time.Unix(1498336884, 0)} + info := bindataFileInfo{name: "image.svg", size: 8984, mode: os.FileMode(0644), modTime: time.Unix(1601471052, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x5a, 0xbf, 0x3a, 0xba, 0x48, 0x3e, 0xf8, 0x9e, 0x6c, 0x7b, 0x48, 0x2f, 0xc2, 0xf3, 0x4, 0xbb, 0x21, 0x1f, 0x2e, 0xfc, 0x14, 0xe4, 0x39, 0x3a, 0x4a, 0x9e, 0x7c, 0xce, 0x3d, 0x81, 0x29, 0xf}} return a, nil } @@ -173,7 +173,7 @@ func imageWebp() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "image.webp", size: 10568, mode: os.FileMode(0644), modTime: time.Unix(1498336884, 0)} + info := bindataFileInfo{name: "image.webp", size: 10568, mode: os.FileMode(0644), modTime: time.Unix(1601471052, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x56, 0x7c, 0xfa, 0xf9, 0x4e, 0xba, 0xf2, 0x79, 0xce, 0xa4, 0xeb, 0xb, 0xc0, 0x5c, 0x46, 0x55, 0x2, 0x1f, 0xb4, 0xee, 0x0, 0x4a, 0xca, 0x52, 0xc0, 0x96, 0x70, 0x9d, 0x3b, 0xa8, 0x7a, 0x63}} return a, nil } @@ -193,7 +193,7 @@ func indexHTML() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "index.html", size: 11363, mode: os.FileMode(0644), modTime: time.Unix(1600622213, 0)} + info := bindataFileInfo{name: "index.html", size: 11363, mode: os.FileMode(0644), modTime: time.Unix(1601471052, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc1, 0x9a, 0x8c, 0xc3, 0x59, 0xa1, 0xa, 0x7f, 0xc1, 0x82, 0xed, 0x60, 0x66, 0xe7, 0x8f, 0xa3, 0xe, 0xab, 0x82, 0x59, 0x2a, 0x4d, 0xb, 0x14, 0xb9, 0x86, 0x35, 0x61, 0xb3, 0x15, 0x7f, 0x4}} return a, nil } @@ -213,7 +213,7 @@ func mobyHTML() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "moby.html", size: 3742, mode: os.FileMode(0644), modTime: time.Unix(1498336884, 0)} + info := bindataFileInfo{name: "moby.html", size: 3742, mode: os.FileMode(0644), modTime: time.Unix(1601471052, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe2, 0x50, 0xa7, 0x97, 0x5d, 0x53, 0x80, 0x1e, 0xd8, 0xc3, 0x52, 0x71, 0x78, 0xa, 0x15, 0xa1, 0xda, 0x36, 0xa8, 0xa5, 0x38, 0x33, 0x27, 0xcb, 0x70, 0x6d, 0xea, 0x25, 0x2b, 0x34, 0xd, 0x48}} return a, nil } @@ -233,7 +233,7 @@ func sampleJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "sample.json", size: 421, mode: os.FileMode(0644), modTime: time.Unix(1562025288, 0)} + info := bindataFileInfo{name: "sample.json", size: 421, mode: os.FileMode(0644), modTime: time.Unix(1601471052, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x91, 0x5, 0x55, 0xf7, 0x43, 0xaf, 0x4a, 0xe6, 0xca, 0x59, 0xa9, 0xed, 0x60, 0x14, 0xff, 0x87, 0xbb, 0xc1, 0x25, 0x69, 0x3, 0x7b, 0xa3, 0x3d, 0x3e, 0x45, 0xec, 0xa9, 0x30, 0xc3, 0x30, 0x20}} return a, nil } @@ -253,7 +253,7 @@ func sampleXML() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "sample.xml", size: 522, mode: os.FileMode(0644), modTime: time.Unix(1498336884, 0)} + info := bindataFileInfo{name: "sample.xml", size: 522, mode: os.FileMode(0644), modTime: time.Unix(1601471052, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x51, 0xc1, 0xe2, 0x6e, 0x8e, 0x42, 0x94, 0x5d, 0x1e, 0xde, 0x78, 0x42, 0x6e, 0x2, 0xe5, 0x42, 0x65, 0x30, 0xdf, 0x74, 0x70, 0x9d, 0xde, 0x51, 0xaf, 0xa2, 0x18, 0x22, 0xa3, 0x50, 0xba, 0x68}} return a, nil } @@ -273,7 +273,7 @@ func utf8HTML() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "utf8.html", size: 14240, mode: os.FileMode(0644), modTime: time.Unix(1498336884, 0)} + info := bindataFileInfo{name: "utf8.html", size: 14240, mode: os.FileMode(0644), modTime: time.Unix(1601471052, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x75, 0x12, 0xcc, 0x55, 0x7d, 0x82, 0x1d, 0x9a, 0x78, 0xa9, 0x7a, 0xc9, 0x74, 0x62, 0x2d, 0x46, 0x3a, 0x5d, 0x37, 0xf8, 0x2a, 0xd7, 0xf6, 0xb0, 0x52, 0xbc, 0xaa, 0x3a, 0xc4, 0x44, 0x1e, 0xc1}} return a, nil } @@ -381,6 +381,9 @@ var _bindata = map[string]func() (*asset, error){ "utf8.html": utf8HTML, } +// AssetDebug is true if the assets were built with the debug flag enabled. +const AssetDebug = false + // AssetDir returns the file names below a certain // directory embedded in the file by go-bindata. // For example if you run go-bindata on data/... and data contains the