Skip to content

Commit c076bad

Browse files
authored
Linting, Refactoring and Badges (we all love badges!) (#255)
1 parent 15e945d commit c076bad

Some content is hidden

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

43 files changed

+778
-315
lines changed

.github/workflows/build-test.yaml

+9-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ on:
33
pull_request:
44
branches:
55
- 'main'
6+
paths:
7+
- "!README.md"
68

79
concurrency:
810
group: ${{ github.workflow }}-${{ github.ref }}
@@ -58,10 +60,13 @@ jobs:
5860
- name: Run all unit tests
5961
run: make test
6062

61-
- name: Check test coverage
62-
run: |
63-
go install github.com/vladopajic/go-test-coverage/v2@latest
64-
go-test-coverage --config=./.testcoverage.yml
63+
- name: check test coverage
64+
uses: vladopajic/go-test-coverage@v2
65+
with:
66+
config: ./.testcoverage.yml
67+
68+
- name: Trigger Coverage update
69+
uses: ./coverage-badge.yaml
6570

6671
- name: Generate code coverage artifacts
6772
uses: actions/upload-artifact@v4

.github/workflows/coverage-badge.yaml

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: Generate code coverage badge
2+
3+
on:
4+
workflow_dispatch: # Here for Testing
5+
workflow_call:
6+
7+
permissions:
8+
contents: write
9+
10+
jobs:
11+
test:
12+
runs-on: ubuntu-latest
13+
name: Update coverage badge
14+
steps:
15+
- name: Checkout
16+
uses: actions/checkout@v4
17+
with:
18+
persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal access token.
19+
fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository.
20+
21+
- name: Setup go
22+
uses: actions/setup-go@v4
23+
with:
24+
go-version-file: 'go.mod'
25+
26+
- name: Run Test
27+
run: |
28+
go test -v ./... -covermode=count -coverprofile=coverage.out
29+
go tool cover -func=coverage.out -o=coverage.out
30+
31+
- name: Go Coverage Badge # Pass the `coverage.out` output to this action
32+
uses: tj-actions/coverage-badge-go@v2
33+
with:
34+
filename: coverage.out
35+
36+
- name: Verify Changed files
37+
uses: tj-actions/verify-changed-files@v16
38+
id: verify-changed-files
39+
with:
40+
files: README.md
41+
42+
- name: Commit changes
43+
if: steps.verify-changed-files.outputs.files_changed == 'true'
44+
run: |
45+
git config --local user.email "[email protected]"
46+
git config --local user.name "GitHub Action"
47+
git add README.md
48+
git commit -m "docs: Updated coverage badge."
49+
50+
- name: Push changes
51+
if: steps.verify-changed-files.outputs.files_changed == 'true'
52+
uses: ad-m/github-push-action@master
53+
with:
54+
github_token: ${{ github.token }}
55+
branch: ${{ github.head_ref }}

.github/workflows/release.yaml

-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ jobs:
5252
include: "Makefile"
5353
regex: true
5454

55-
5655
- name: Install Helm Docs
5756
uses: envoy/[email protected]
5857
with:
@@ -94,7 +93,6 @@ jobs:
9493
id: github_release
9594
uses: mikepenz/release-changelog-builder-action@v5
9695

97-
9896
- name: Create Release PR
9997
uses: devops-infra/[email protected]
10098
with:

README.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# version-checker
22

3+
![GitHub Release](https://img.shields.io/github/v/release/jetstack/version-checker)
4+
[![Go Report Card](https://goreportcard.com/badge/github.com/jetstack/version-checker)](https://goreportcard.com/report/github.com/jetstack/version-checker)
5+
[![Tests](https://github.com/jetstack/version-checker/actions/workflows/build-test.yaml/badge.svg)](https://github.com/jetstack/version-checker/actions/workflows/build-test.yaml?query=branch%3Amain)
6+
![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/jetstack/version-checker)
7+
38
version-checker is a Kubernetes utility for observing the current versions of
49
images running in the cluster, as well as the latest available upstream. These
510
checks get exposed as Prometheus metrics to be viewed on a dashboard, or _soft_

cmd/app/app.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func NewCommand(ctx context.Context) *cobra.Command {
2727
Use: "version-checker",
2828
Short: helpOutput,
2929
Long: helpOutput,
30-
RunE: func(cmd *cobra.Command, args []string) error {
30+
RunE: func(_ *cobra.Command, _ []string) error {
3131
opts.complete()
3232

3333
logLevel, err := logrus.ParseLevel(opts.LogLevel)

cmd/app/options.go

+38-40
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ var (
6060
selfhostedInsecureReg = regexp.MustCompile("^VERSION_CHECKER_SELFHOSTED_INSECURE_(.*)")
6161
)
6262

63-
// Options is a struct to hold options for the version-checker
63+
// Options is a struct to hold options for the version-checker.
6464
type Options struct {
6565
MetricsServingAddress string
6666
DefaultTestAll bool
@@ -88,7 +88,7 @@ func (o *Options) addFlags(cmd *cobra.Command) {
8888
return nil
8989
})
9090

91-
cmd.SetHelpFunc(func(cmd *cobra.Command, args []string) {
91+
cmd.SetHelpFunc(func(cmd *cobra.Command, _ []string) {
9292
fmt.Fprintf(cmd.OutOrStdout(), "%s\n\n"+usageFmt, cmd.Long, cmd.UseLine())
9393
cliflag.PrintSections(cmd.OutOrStdout(), nfs, 0)
9494
})
@@ -329,55 +329,53 @@ func (o *Options) assignSelfhosted(envs []string) {
329329
}
330330
}
331331

332-
for _, env := range envs {
333-
pair := strings.SplitN(env, "=", 2)
334-
if len(pair) != 2 || len(pair[1]) == 0 {
335-
continue
336-
}
337-
338-
if matches := selfhostedHostReg.FindStringSubmatch(strings.ToUpper(pair[0])); len(matches) == 2 {
332+
regexActions := map[*regexp.Regexp]func(matches []string, value string){
333+
selfhostedHostReg: func(matches []string, value string) {
339334
initOptions(matches[1])
340-
o.Client.Selfhosted[matches[1]].Host = pair[1]
341-
continue
342-
}
343-
344-
if matches := selfhostedUsernameReg.FindStringSubmatch(strings.ToUpper(pair[0])); len(matches) == 2 {
335+
o.Client.Selfhosted[matches[1]].Host = value
336+
},
337+
selfhostedUsernameReg: func(matches []string, value string) {
345338
initOptions(matches[1])
346-
o.Client.Selfhosted[matches[1]].Username = pair[1]
347-
continue
348-
}
349-
350-
if matches := selfhostedPasswordReg.FindStringSubmatch(strings.ToUpper(pair[0])); len(matches) == 2 {
339+
o.Client.Selfhosted[matches[1]].Username = value
340+
},
341+
selfhostedPasswordReg: func(matches []string, value string) {
351342
initOptions(matches[1])
352-
o.Client.Selfhosted[matches[1]].Password = pair[1]
353-
continue
354-
}
355-
356-
if matches := selfhostedTokenPath.FindStringSubmatch(strings.ToUpper(pair[0])); len(matches) == 2 {
343+
o.Client.Selfhosted[matches[1]].Password = value
344+
},
345+
selfhostedTokenPath: func(matches []string, value string) {
357346
initOptions(matches[1])
358-
o.Client.Selfhosted[matches[1]].TokenPath = pair[1]
359-
continue
360-
}
361-
362-
if matches := selfhostedTokenReg.FindStringSubmatch(strings.ToUpper(pair[0])); len(matches) == 2 {
347+
o.Client.Selfhosted[matches[1]].TokenPath = value
348+
},
349+
selfhostedTokenReg: func(matches []string, value string) {
363350
initOptions(matches[1])
364-
o.Client.Selfhosted[matches[1]].Bearer = pair[1]
365-
continue
366-
}
367-
368-
if matches := selfhostedInsecureReg.FindStringSubmatch(strings.ToUpper(pair[0])); len(matches) == 2 {
351+
o.Client.Selfhosted[matches[1]].Bearer = value
352+
},
353+
selfhostedInsecureReg: func(matches []string, value string) {
369354
initOptions(matches[1])
370-
val, err := strconv.ParseBool(pair[1])
371-
if err == nil {
355+
if val, err := strconv.ParseBool(value); err == nil {
372356
o.Client.Selfhosted[matches[1]].Insecure = val
373357
}
358+
},
359+
selfhostedCAPath: func(matches []string, value string) {
360+
initOptions(matches[1])
361+
o.Client.Selfhosted[matches[1]].CAPath = value
362+
},
363+
}
364+
365+
for _, env := range envs {
366+
pair := strings.SplitN(env, "=", 2)
367+
if len(pair) != 2 || len(pair[1]) == 0 {
374368
continue
375369
}
376370

377-
if matches := selfhostedCAPath.FindStringSubmatch(strings.ToUpper(pair[0])); len(matches) == 2 {
378-
initOptions(matches[1])
379-
o.Client.Selfhosted[matches[1]].CAPath = pair[1]
380-
continue
371+
key := strings.ToUpper(pair[0])
372+
value := pair[1]
373+
374+
for regex, action := range regexActions {
375+
if matches := regex.FindStringSubmatch(key); len(matches) == 2 {
376+
action(matches, value)
377+
break
378+
}
381379
}
382380
}
383381

cmd/app/options_test.go

+12-13
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func TestComplete(t *testing.T) {
7373
Token: "quay-token",
7474
},
7575
Selfhosted: map[string]*selfhosted.Options{
76-
"FOO": &selfhosted.Options{
76+
"FOO": {
7777
Host: "docker.joshvanl.com",
7878
Username: "joshvanl",
7979
Password: "password",
@@ -141,21 +141,21 @@ func TestComplete(t *testing.T) {
141141
Token: "quay-token",
142142
},
143143
Selfhosted: map[string]*selfhosted.Options{
144-
"FOO": &selfhosted.Options{
144+
"FOO": {
145145
Host: "docker.joshvanl.com",
146146
Username: "joshvanl",
147147
Password: "password",
148148
Bearer: "my-token",
149149
Insecure: true,
150150
},
151-
"BAR": &selfhosted.Options{
151+
"BAR": {
152152
Host: "bar.docker.joshvanl.com",
153153
Username: "bar.joshvanl",
154154
Password: "bar-password",
155155
Bearer: "my-bar-token",
156156
Insecure: false,
157157
},
158-
"BUZZ": &selfhosted.Options{
158+
"BUZZ": {
159159
Host: "buzz.docker.jetstack.io",
160160
Username: "buzz.davidcollom",
161161
Password: "buzz-password",
@@ -208,7 +208,7 @@ func TestAssignSelfhosted(t *testing.T) {
208208
},
209209
expOptions: client.Options{
210210
Selfhosted: map[string]*selfhosted.Options{
211-
"FOO": &selfhosted.Options{
211+
"FOO": {
212212
Host: "docker.joshvanl.com",
213213
Username: "joshvanl",
214214
Password: "password",
@@ -228,13 +228,13 @@ func TestAssignSelfhosted(t *testing.T) {
228228
},
229229
expOptions: client.Options{
230230
Selfhosted: map[string]*selfhosted.Options{
231-
"FOO": &selfhosted.Options{
231+
"FOO": {
232232
Host: "docker.joshvanl.com",
233233
Username: "joshvanl",
234234
Password: "password",
235235
Bearer: "my-token",
236236
},
237-
"BAR": &selfhosted.Options{
237+
"BAR": {
238238
Host: "hello.world.com",
239239
Bearer: "my-bar-token",
240240
},
@@ -253,14 +253,14 @@ func TestAssignSelfhosted(t *testing.T) {
253253
},
254254
expOptions: client.Options{
255255
Selfhosted: map[string]*selfhosted.Options{
256-
"FOO": &selfhosted.Options{
256+
"FOO": {
257257
Host: "docker.joshvanl.com",
258258
Username: "joshvanl",
259259
Password: "password",
260260
Bearer: "my-token",
261261
TokenPath: "/artifactory/api/security/token",
262262
},
263-
"BAR": &selfhosted.Options{
263+
"BAR": {
264264
Host: "hello.world.com",
265265
Bearer: "my-bar-token",
266266
},
@@ -281,17 +281,17 @@ func TestAssignSelfhosted(t *testing.T) {
281281
},
282282
expOptions: client.Options{
283283
Selfhosted: map[string]*selfhosted.Options{
284-
"FOO": &selfhosted.Options{
284+
"FOO": {
285285
Host: "docker.joshvanl.com",
286286
Username: "joshvanl",
287287
Password: "password",
288288
Bearer: "my-token",
289289
},
290-
"BAR": &selfhosted.Options{
290+
"BAR": {
291291
Host: "hello.world.com",
292292
Bearer: "my-bar-token",
293293
},
294-
"JOSHVANL": &selfhosted.Options{
294+
"JOSHVANL": {
295295
Host: "joshvanl.com",
296296
},
297297
},
@@ -301,7 +301,6 @@ func TestAssignSelfhosted(t *testing.T) {
301301

302302
for name, test := range tests {
303303
t.Run(name, func(t *testing.T) {
304-
305304
o := new(Options)
306305
o.assignSelfhosted(test.envs)
307306

deploy/charts/version-checker/README.md

+6
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ A Helm chart for version-checker
5656
| replicaCount | int | `1` | Replica Count for version-checker |
5757
| resources | object | `{}` | Setup version-checkers resource requests/limits |
5858
| securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true,"runAsNonRoot":true,"runAsUser":65534,"seccompProfile":{"type":"RuntimeDefault"}}` | Set container-level security context |
59+
| securityContext.allowPrivilegeEscalation | bool | `false` | Prevent the container from PrivilegeEscalation |
60+
| securityContext.capabilities | object | `{"drop":["ALL"]}` | Ensure that we run with the capabilities we explicitly need to run |
61+
| securityContext.readOnlyRootFilesystem | bool | `true` | Readonly Filesystem |
62+
| securityContext.runAsNonRoot | bool | `true` | Ensure we don't run as root |
63+
| securityContext.runAsUser | int | `65534` | Specify UID to run under |
64+
| securityContext.seccompProfile | object | `{"type":"RuntimeDefault"}` | SeccomProfile to use |
5965
| selfhosted | []{name: "", host: "", username:"", password:"", token:""}] | `[]` | Setup a number of SelfHosted Repositories and their credentials |
6066
| service.annotations | object | `{}` | Additional annotations to add to the service |
6167
| service.labels | object | `{}` | Additional labels to add to the service |

deploy/charts/version-checker/templates/_helpers.tpl

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,4 @@ Common selector
3232
{{- define "version-checker.selector" -}}
3333
app.kubernetes.io/name: {{ include "version-checker.name" . }}
3434
app.kubernetes.io/instance: {{ .Release.Name }}
35-
{{- end -}}
35+
{{- end -}}

deploy/charts/version-checker/values.yaml

+6
Original file line numberDiff line numberDiff line change
@@ -127,13 +127,19 @@ resources:
127127

128128
# -- Set container-level security context
129129
securityContext:
130+
# -- Prevent the container from PrivilegeEscalation
130131
allowPrivilegeEscalation: false
132+
# -- Ensure that we run with the capabilities we explicitly need to run
131133
capabilities:
132134
drop:
133135
- ALL
136+
# -- Readonly Filesystem
134137
readOnlyRootFilesystem: true
138+
# -- Ensure we don't run as root
135139
runAsNonRoot: true
140+
# -- Specify UID to run under
136141
runAsUser: 65534
142+
# -- SeccomProfile to use
137143
seccompProfile:
138144
type: RuntimeDefault
139145

0 commit comments

Comments
 (0)