Skip to content

Commit f7853f4

Browse files
authored
Ethanperry/build pipeline (#23)
Improve build pipelines and introduce test run pipeline for krill project.
2 parents 5d9aa48 + c413218 commit f7853f4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+1653
-898
lines changed

.github/workflows/docker_build.yml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,13 @@ jobs:
5656
context: ${{ inputs.context }}
5757
file: ${{ inputs.file }}
5858
push: true
59-
cache-from: type=gha
60-
cache-to: type=gha,mode=max
59+
60+
- name: Build and Push if Pushed with Tag
61+
uses: docker/build-push-action@v5
62+
with:
63+
tags: |
64+
${{ inputs.registry }}:${{ github.ref_name }}
65+
context: ${{ inputs.context }}
66+
file: ${{ inputs.file }}
67+
push: true
68+
if: ${{ github.event_name == 'push' }}

.github/workflows/krill_build.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@ name: krill_build
33
on:
44
workflow_dispatch:
55
push:
6-
paths:
7-
- samples/krill/**
6+
tags:
7+
- 'v*.*.*-krill'
88

99
jobs:
1010
call-docker-build:
1111
uses: ./.github/workflows/docker_build.yml
1212
with:
13-
registry: azbluefin.azurecr.io/krill
14-
file: Dockerfile
15-
context: ./samples/krill/
13+
registry: makocr.azurecr.io/krill
14+
file: samples/krill/Dockerfile
15+
context: .
1616
secrets:
1717
azureCredentials: ${{ secrets.AZURE_CREDENTIALS }}
1818
registryLoginServer: ${{ secrets.REGISTRY_LOGIN_SERVER }}

.github/workflows/krill_test.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
name: krill_test
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
paths:
7+
- samples/krill/**
8+
9+
jobs:
10+
call-mage-test:
11+
uses: ./.github/workflows/mage_tests.yml
12+
with:
13+
workdir: samples/krill/

.github/workflows/mage_tests.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: mage_tests
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
workdir:
7+
required: true
8+
type: string
9+
10+
11+
jobs:
12+
mage_test:
13+
name: "Runs golang tests using mage command provided in libraries"
14+
runs-on: ubuntu-latest
15+
16+
defaults:
17+
run:
18+
shell: bash
19+
20+
steps:
21+
- name: Checkout
22+
uses: actions/checkout@v4
23+
24+
- name: Setup Go 1.21
25+
uses: actions/setup-go@v4
26+
with:
27+
go-version: 1.21
28+
29+
- name: Install Mage
30+
run: |
31+
go install github.com/magefile/mage@latest
32+
33+
- name: Run CI Verification
34+
working-directory: ${{ inputs.workdir }}
35+
run: |
36+
mage ci

lib/mage/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module github.com/Azure-Samples/explore-iot-operations/lib/mage
1+
module github.com/explore-iot-operations/lib/mage
22

33
go 1.21.3
44

lib/mage/mageerrors.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package main
1+
package mage
22

33
import "fmt"
44

lib/mage/magefile.go

Lines changed: 29 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
1-
//go:build mage
2-
// +build mage
3-
4-
package main
1+
package mage
52

63
import (
74
"encoding/json"
85
"fmt"
96
"io"
7+
"strconv"
108
"strings"
119

1210
"github.com/magefile/mage/sh"
1311
"github.com/princjef/mageutil/bintool"
12+
"github.com/princjef/mageutil/shellcmd"
1413
)
1514

1615
var (
@@ -28,37 +27,6 @@ var (
2827
"0.4.1",
2928
"https://github.com/princjef/gomarkdoc/releases/download/v{{.Version}}/gomarkdoc_{{.Version}}_{{.GOOS}}_{{.GOARCH}}{{.ArchiveExt}}",
3029
))
31-
releaser = bintool.Must(bintool.NewGo(
32-
"github.com/goreleaser/goreleaser",
33-
"v1.18.2",
34-
))
35-
)
36-
37-
const (
38-
KRILL project = "krill"
39-
)
40-
41-
var projects = []project{
42-
KRILL,
43-
}
44-
45-
var buildProjectPathMap map[project]string = map[project]string{
46-
KRILL: "./cmd/krill",
47-
}
48-
49-
var releasePathMap map[project]string = map[project]string{
50-
KRILL: "./releases/krill/.goreleaser.yaml",
51-
}
52-
53-
const (
54-
// UnitTestTimeoutMs specifies the maximum amount of time a unit test will be given before it is considered failed.
55-
UnitTestTimeoutMs = 3000
56-
57-
// ExpectedBlockCoverage describes the minimum expected test coverage of each code block.
58-
ExpectedBlockCoverage = 0.00
59-
60-
// ExpectedOverallCoverage describes the minimum expected test coverage of the overall codebase.
61-
ExpectedOverallCoverage = 85.00
6230
)
6331

6432
func ensureFormatter() error {
@@ -73,10 +41,6 @@ func ensureDocumenter() error {
7341
return documenter.Ensure()
7442
}
7543

76-
func ensureReleaser() error {
77-
return releaser.Ensure()
78-
}
79-
8044
func EnsureAllTools() error {
8145
if err := ensureFormatter(); err != nil {
8246
return err
@@ -90,10 +54,6 @@ func EnsureAllTools() error {
9054
return err
9155
}
9256

93-
if err := ensureReleaser(); err != nil {
94-
return err
95-
}
96-
9757
return nil
9858
}
9959

@@ -132,7 +92,8 @@ func Clean() error {
13292

13393
// Cover runs tests and generates coverage profiles for all tests.
13494
// The tests run in atomic mode and check for race conditions.
135-
func Cover() error {
95+
// UnitTestTimeoutMs specifies the maximum amount of time a unit test will be given before it is considered failed.
96+
func Cover(unitTestTimeoutMs int) error {
13697
err := Clean()
13798
if err != nil {
13899
return err
@@ -142,7 +103,7 @@ func Cover() error {
142103
"go",
143104
"test",
144105
"-timeout",
145-
fmt.Sprintf("%dms", UnitTestTimeoutMs),
106+
fmt.Sprintf("%dms", unitTestTimeoutMs),
146107
"-cover",
147108
"--coverprofile=cover.tmp.out",
148109
"-covermode=atomic",
@@ -161,24 +122,18 @@ func Cover() error {
161122
return sh.RunV("go", "tool", "cover", "-func=coverage.out")
162123
}
163124

164-
165125
// Package is a subset of the structure returned by the go list tool.
166126
type Package struct {
167127
TestGoFiles []string `json:"TestGoFiles"`
168128
XTestGoFiles []string `json:"XTestGoFiles"`
169129
ImportPath string `json:"ImportPath"`
170130
}
171131

172-
// ImportPathRoot is the root import for all packages in this project.
173-
const ImportPathRoot = "dev.azure.com/msazure/One/_git/Digital-Operations-Experience/service/"
174-
175-
// TestPackageExclusions is a set of packages which are excluded from the check for at least one test file.
176-
// This should only include the main package and any packages which only define types or constants.
177-
var TestPackageExclusions = map[string]any{}
178-
179132
// EnsureTests ensures that every package besides those excluded via the "TestPackageExclusions" variable defined above must contain at least one test file.
180133
// This ensures that coverage will be measured for all packages and forces the creation of test files for all new packages.
181-
func EnsureTests() error {
134+
// TestPackageExclusions is a set of packages which are excluded from the check for at least one test file.
135+
// This should only include the main package and any packages which only define types or constants.
136+
func EnsureTests(importPathRoot string, testPackageExclusions map[string]any) error {
182137
res, err := sh.Output("go", "list", "-json", "./...")
183138
if err != nil {
184139
return err
@@ -200,7 +155,7 @@ func EnsureTests() error {
200155
}
201156

202157
for _, pack := range packages {
203-
if _, ok := TestPackageExclusions[strings.TrimPrefix(pack.ImportPath, ImportPathRoot)]; ok {
158+
if _, ok := testPackageExclusions[strings.TrimPrefix(pack.ImportPath, importPathRoot)]; ok {
204159
continue
205160
}
206161
if len(pack.XTestGoFiles) < 1 && len(pack.TestGoFiles) < 1 {
@@ -221,7 +176,9 @@ func Bench() error {
221176
// EvaluateCoverage takes a coverage file and evaluates the coverage of code block and overall app unit test coverage.
222177
// If the coverage of any given block or the overall coverage of the application does not meet the above
223178
// thresholds, an error will be returned. Otherwise a message describing coverage will be reported.
224-
func EvaluateCoverage() error {
179+
// ExpectedBlockCoverage describes the minimum expected test coverage of each code block.
180+
// ExpectedOverallCoverage describes the minimum expected test coverage of the overall codebase.
181+
func EvaluateCoverage(expectedBlockCoverage, expectedOverallCoverage float64) error {
225182
res, err := sh.Output(
226183
"go",
227184
"tool",
@@ -261,20 +218,20 @@ func EvaluateCoverage() error {
261218
path: components[0],
262219
name: components[1],
263220
percentage: percentage,
264-
expected: ExpectedBlockCoverage,
221+
expected: expectedBlockCoverage,
265222
}
266223
}
267224

268225
for _, coverage := range coverages {
269-
if coverage.percentage < ExpectedBlockCoverage {
226+
if coverage.percentage < expectedBlockCoverage {
270227
return coverage
271228
}
272229
}
273230

274-
if totalCoverage.percentage < ExpectedOverallCoverage {
231+
if totalCoverage.percentage < expectedOverallCoverage {
275232
return &InadequateOverallCoverageError{
276233
percentage: totalCoverage.percentage,
277-
expected: ExpectedOverallCoverage,
234+
expected: expectedOverallCoverage,
278235
}
279236
}
280237

@@ -286,57 +243,41 @@ func EvaluateCoverage() error {
286243
return nil
287244
}
288245

289-
func Build(proj string) error {
290-
291-
path, ok := buildProjectPathMap[project(proj)]
292-
if !ok {
293-
return fmt.Errorf("invalid project name, must be one of the following: %v", projects)
294-
}
295-
296-
err := EnsureAllTools()
297-
if err != nil {
298-
return err
299-
}
300-
301-
err = Cover()
302-
if err != nil {
303-
return err
304-
}
305-
246+
func Build(proj string, path string) error {
306247
return sh.RunV("go", "build", "-o", proj, path)
307248
}
308249

309-
func Release(proj string, version string, message string) error {
310-
311-
path, ok := releasePathMap[project(proj)]
312-
if !ok {
313-
return fmt.Errorf("invalid project name, must be one of the following: %v", projects)
314-
}
250+
func CI(
251+
importPathRoot string,
252+
testPackageExclusions map[string]any,
253+
unitTestTimeoutMs int,
254+
expectedBlockCoverage, expectedOverallCoverage float64,
255+
) error {
315256

316257
err := EnsureAllTools()
317258
if err != nil {
318259
return err
319260
}
320261

321-
err = Cover()
262+
err = Lint()
322263
if err != nil {
323264
return err
324265
}
325266

326-
err = sh.RunV("goreleaser", "check", path)
267+
err = Format()
327268
if err != nil {
328269
return err
329270
}
330271

331-
err = sh.RunV("git", "tag", "-a", version, "-m", message)
272+
err = EnsureTests(importPathRoot, testPackageExclusions)
332273
if err != nil {
333274
return err
334275
}
335276

336-
err = sh.RunV("git", "push", "origin", version)
277+
err = Cover(unitTestTimeoutMs)
337278
if err != nil {
338279
return err
339280
}
340281

341-
return sh.RunV("goreleaser", "release", "--clean", "-f", path)
282+
return EvaluateCoverage(expectedBlockCoverage, expectedOverallCoverage)
342283
}

lib/proto/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ require (
1212
github.com/davecgh/go-spew v1.1.1 // indirect
1313
github.com/golang/protobuf v1.5.3 // indirect
1414
github.com/pmezard/go-difflib v1.0.0 // indirect
15-
golang.org/x/net v0.14.0 // indirect
15+
golang.org/x/net v0.17.0 // indirect
1616
golang.org/x/sys v0.11.0 // indirect
1717
golang.org/x/text v0.12.0 // indirect
1818
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect

samples/krill/Dockerfile

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@
22

33
FROM mcr.microsoft.com/oss/go/microsoft/golang:1.21-cbl-mariner2.0 AS build
44

5-
COPY . /app
5+
COPY ./lib /workdir/lib
66

7-
WORKDIR /app
7+
COPY ./samples/krill /workdir/samples/krill
8+
9+
WORKDIR /workdir/samples/krill
810

911
RUN go mod download
1012

11-
RUN go fmt ./...
13+
RUN go install github.com/magefile/mage@latest
14+
15+
RUN mage ci
1216

1317
RUN go build -o ./bin/krill ./cmd/krill
1418

0 commit comments

Comments
 (0)