-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: change the sample application (#33)
* feat: change the sample application * ci: add `docker-publish` * ci: add `makefile` * ci(pre-commit): add `actionlint` hook * docs(README): add `image` info
- Loading branch information
Showing
11 changed files
with
308 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
name: Docker | ||
|
||
on: | ||
push: | ||
branches: ["main"] | ||
tags: ["v*.*.*"] | ||
pull_request: | ||
branches: ["main"] | ||
|
||
permissions: | ||
contents: read | ||
|
||
env: | ||
# Use docker.io for Docker Hub if empty | ||
REGISTRY: ghcr.io | ||
# github.repository as <account>/<repo> | ||
IMAGE_NAME: ${{ github.repository }} | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
permissions: | ||
packages: write | ||
# This is used to complete the identity challenge | ||
# with sigstore/fulcio when running outside of PRs. | ||
id-token: write | ||
# To upload sarif files. | ||
security-events: write | ||
|
||
steps: | ||
- name: Checkout repository | ||
uses: actions/checkout@v4 | ||
|
||
# Install the cosign tool except on PR. | ||
- name: Install cosign | ||
if: github.event_name != 'pull_request' | ||
uses: sigstore/cosign-installer@11086d25041f77fe8fe7b9ea4e48e3b9192b8f19 # v3.1.2 | ||
|
||
# Add support for more platforms with QEMU. | ||
- name: Setup QEMU | ||
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 | ||
|
||
# Using it to be able to build multi-platform images, export cache, etc. | ||
- name: Setup Docker buildx | ||
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 | ||
|
||
# Login against a Docker registry except on PR. | ||
- name: Log into registry ${{ env.REGISTRY }} | ||
if: github.event_name != 'pull_request' | ||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 | ||
with: | ||
registry: ${{ env.REGISTRY }} | ||
username: ${{ github.actor }} | ||
password: ${{ secrets.GITHUB_TOKEN }} | ||
|
||
# Extract metadata (tags, labels) for Docker. | ||
- name: Extract Docker metadata | ||
id: meta | ||
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0 | ||
with: | ||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | ||
|
||
# Build and push Docker image with Buildx (don't push on PR). | ||
- name: Build and push Docker image | ||
id: build-and-push | ||
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0 | ||
with: | ||
context: . | ||
push: ${{ github.event_name != 'pull_request' }} | ||
tags: ${{ steps.meta.outputs.tags }} | ||
labels: ${{ steps.meta.outputs.labels }} | ||
cache-from: type=gha | ||
cache-to: type=gha,mode=max | ||
platforms: linux/amd64,linux/arm64 | ||
|
||
# Sign the resulting Docker image digest except on PRs. | ||
- name: Sign the published Docker image | ||
if: ${{ github.event_name != 'pull_request' }} | ||
env: | ||
TAGS: ${{ steps.meta.outputs.tags }} | ||
DIGEST: ${{ steps.build-and-push.outputs.digest }} | ||
# This step uses the identity token to provision an ephemeral certificate | ||
# against the sigstore community Fulcio instance. | ||
run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST} | ||
|
||
# Analyze vulnerabilities. | ||
- name: Run Trivy vulnerability scanner | ||
if: ${{ github.event_name != 'pull_request' }} | ||
uses: aquasecurity/trivy-action@fbd16365eb88e12433951383f5e99bd901fc618f # v0.12.0 | ||
with: | ||
image-ref: ${{ steps.meta.outputs.tags }} | ||
format: "sarif" | ||
output: "trivy-results.sarif" | ||
|
||
# Upload report to GitHub code scanning. | ||
- name: Upload Trivy scan results to GitHub Security tab | ||
if: ${{ github.event_name != 'pull_request' }} | ||
uses: github/codeql-action/upload-sarif@v2 | ||
with: | ||
sarif_file: "trivy-results.sarif" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,9 @@ | |
*.so | ||
*.dylib | ||
|
||
# Distribution | ||
dist/ | ||
|
||
# Test binary, built with `go test -c` | ||
*.test | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Build the application from source. | ||
FROM golang:1.21-alpine@sha256:96634e55b363cb93d39f78fb18aa64abc7f96d372c176660d7b8b6118939d97b AS go-builder | ||
|
||
WORKDIR /tmp/app | ||
COPY go.mod go.sum cmd ./ | ||
RUN go build -o /tmp/deadnews-template-go ./... | ||
|
||
# Deploy the application binary into a lean image. | ||
FROM gcr.io/distroless/static-debian12:latest@sha256:98e138282ba524ff4f5124fec603f82ee2331df4ba981d169b3ded8bcd83ca52 AS final | ||
|
||
WORKDIR / | ||
COPY --from=go-builder /tmp/deadnews-template-go /bin/deadnews-template-go | ||
|
||
USER nonroot:nonroot | ||
EXPOSE 1271 | ||
HEALTHCHECK --interval=60s --timeout=3s CMD curl --fail http://127.0.0.1:1271/health || exit 1 | ||
|
||
CMD ["/bin/deadnews-template-go"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
run_app: | ||
go run cmd/deadnews-template-go/main.go | ||
|
||
test: | ||
go test -v -race -covermode=atomic -coverprofile='coverage.txt' ./... | ||
|
||
build: | ||
go build -o ./dist/ ./... | ||
|
||
.PHONY: test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,61 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
"os" | ||
|
||
"github.com/labstack/echo/v4" | ||
"github.com/labstack/echo/v4/middleware" | ||
) | ||
|
||
// Get answer to the Meaning of Life, the Universe, and Everything. | ||
func GetAnswer() int { | ||
result := 40 + 2 | ||
return result | ||
// This code is the main function of a Go program | ||
// that creates and starts a server using the Echo framework. | ||
// It retrieves the value of the "PORT" environment variable | ||
// and if it is not set, it defaults to port 1271. | ||
func main() { | ||
// Create a new Echo instance. | ||
e := makeServer() | ||
|
||
// Get the value of the "PORT" environment variable. | ||
httpPort := os.Getenv("PORT") | ||
if httpPort == "" { | ||
httpPort = "1271" | ||
} | ||
|
||
// Start the server on the specified port. | ||
e.Logger.Fatal(e.Start(":" + httpPort)) | ||
} | ||
|
||
func main() { | ||
fmt.Println(GetAnswer()) | ||
// Output: 42 | ||
// makeServer creates a new instance of the Echo framework | ||
// and configures it with middleware for logging and error recovery. | ||
// It also defines two route handlers: one for the root ("/") route that returns an HTML response, | ||
// and another for the "/health" route that returns a JSON response. | ||
// | ||
// Returns: | ||
// - A configured instance of the Echo framework. | ||
func makeServer() *echo.Echo { | ||
// Create a new Echo instance. | ||
e := echo.New() | ||
|
||
// Use middleware for logging and error recovery. | ||
e.Use(middleware.Logger()) | ||
e.Use(middleware.Recover()) | ||
|
||
// Define the "/" route handler. | ||
e.GET("/", handleRoot) | ||
|
||
// Define the "/health" route handler. | ||
e.GET("/health", handleHealth) | ||
|
||
return e | ||
} | ||
|
||
// handleRoot handles the "/" route and returns an HTML response. | ||
func handleRoot(c echo.Context) error { | ||
return c.HTML(http.StatusOK, "Hello, World!") | ||
} | ||
|
||
// handleHealth handles the "/health" route and returns a JSON response. | ||
func handleHealth(c echo.Context) error { | ||
return c.JSON(http.StatusOK, struct{ Status string }{Status: "OK"}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,68 @@ | ||
package main | ||
|
||
import ( | ||
"net/http" | ||
"net/http/httptest" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestGetAnswer(t *testing.T) { | ||
assert := assert.New(t) | ||
func TestServerCreation(t *testing.T) { | ||
e := makeServer() | ||
|
||
assert.Equal(42, GetAnswer(), "they should be equal") | ||
assert.NotNil(t, e.GET("/", handleRoot)) | ||
assert.NotNil(t, e.GET("/health", handleHealth)) | ||
} | ||
|
||
func TestServerResponseRoot(t *testing.T) { | ||
// Create a new Echo instance. | ||
e := makeServer() | ||
|
||
// Create a new HTTP request to the root route. | ||
req := httptest.NewRequest(http.MethodGet, "/", nil) | ||
|
||
// Create a new HTTP response recorder. | ||
rec := httptest.NewRecorder() | ||
|
||
// Handle the request. | ||
e.ServeHTTP(rec, req) | ||
|
||
// Check the actual status code against the expected status code. | ||
expectedStatus := http.StatusOK | ||
assert.Equal(t, expectedStatus, rec.Code) | ||
|
||
// Check the actual response body against the expected response body. | ||
expectedBody := "Hello, World!" | ||
assert.Equal(t, expectedBody, rec.Body.String()) | ||
|
||
// Check the response content type header. | ||
contentType := "text/html; charset=UTF-8" | ||
assert.Equal(t, contentType, rec.Header().Get("Content-Type")) | ||
} | ||
|
||
func TestServerResponseHealth(t *testing.T) { | ||
// Create a new Echo instance. | ||
e := makeServer() | ||
|
||
// Create a new HTTP request with the "/health" route. | ||
req := httptest.NewRequest(http.MethodGet, "/health", nil) | ||
|
||
// Create a new HTTP response recorder. | ||
rec := httptest.NewRecorder() | ||
|
||
// Handle the request. | ||
e.ServeHTTP(rec, req) | ||
|
||
// Check the actual status code against the expected status code. | ||
expectedStatus := http.StatusOK | ||
assert.Equal(t, expectedStatus, rec.Code) | ||
|
||
// Check the actual response body against the expected response body. | ||
expectedBody := `{"Status":"OK"}` + "\n" | ||
assert.Equal(t, expectedBody, rec.Body.String()) | ||
|
||
// Check the response content type header. | ||
contentType := "application/json; charset=UTF-8" | ||
assert.Equal(t, contentType, rec.Header().Get("Content-Type")) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,25 @@ | ||
module github.com/DeadNews/deadnews-template-go | ||
|
||
go 1.20 | ||
go 1.21 | ||
|
||
require github.com/stretchr/testify v1.8.4 | ||
require ( | ||
github.com/labstack/echo/v4 v4.11.1 | ||
github.com/stretchr/testify v1.8.4 | ||
) | ||
|
||
require ( | ||
github.com/davecgh/go-spew v1.1.1 // indirect | ||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect | ||
github.com/labstack/gommon v0.4.0 // indirect | ||
github.com/mattn/go-colorable v0.1.13 // indirect | ||
github.com/mattn/go-isatty v0.0.19 // indirect | ||
github.com/pmezard/go-difflib v1.0.0 // indirect | ||
github.com/valyala/bytebufferpool v1.0.0 // indirect | ||
github.com/valyala/fasttemplate v1.2.2 // indirect | ||
golang.org/x/crypto v0.13.0 // indirect | ||
golang.org/x/net v0.15.0 // indirect | ||
golang.org/x/sys v0.12.0 // indirect | ||
golang.org/x/text v0.13.0 // indirect | ||
golang.org/x/time v0.3.0 // indirect | ||
gopkg.in/yaml.v3 v3.0.1 // indirect | ||
) |
Oops, something went wrong.