Skip to content

Commit

Permalink
Remove dependency on Mage (#332)
Browse files Browse the repository at this point in the history
[Mage][1] is a Go build tool which we were using to invoke our label
checking Go function and to build our Go binary. We don't need Mage
though, as we can simply use the standard Go `main` function and build
the binary using the standard `go build` command.

It's always good to remove unneeded dependencies, and also Mage was
responsible for setting the beginning of the error output (`Error:`)
that is displayed on the console.  By removing Mage we now have control
of this.  This paves the way for making the error output a [GitHub
Actions  workflow command][2] in a future PR, which will mean the error
message is highlighted (which will fix #330).

[1]: https://magefile.org/
[2]: https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-error-message
  • Loading branch information
johnboyes committed Feb 11, 2023
1 parent e7993d1 commit 318a78c
Show file tree
Hide file tree
Showing 11 changed files with 45 additions and 63 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/integration_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@ jobs:
env:
INPUT_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
go test -integration -v .
go test -integration -enterprise-cloud -v .
go test ./... -integration -v
go test ./... -integration -enterprise-cloud -v
6 changes: 3 additions & 3 deletions .github/workflows/virtual_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,6 @@ jobs:
run: install-and-trust-hoverfly-default-cert.sh
- name: Tests
run: |
go test -v .
go test -enterprise-cloud -v .
go test -enterprise-server -v .
go test ./... -v
go test ./... -enterprise-cloud -v
go test ./... -enterprise-server -v
16 changes: 5 additions & 11 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ Firstly thanks for thinking of contributing - the project is [open source](https
* [Tools and technologies](#tools-and-technologies)
* [GitHub Actions](#github-actions)
* [Go](#go)
* [Mage](#mage)

[Running the tests](#running-the-tests)

## How to report a bug or suggest a new feature
Expand Down Expand Up @@ -72,39 +70,35 @@ Some reasons we chose [Go](https://golang.org/):
* [ease of deployment](https://hub.packtpub.com/cloud-native-go-programming/)
* [backwards compatibility](https://yourbasic.org/golang/advantages-over-java-python/#compatibility)

#### Mage

The application is built using [Mage](https://magefile.org/), which is the Go equivalent of [Make](https://www.gnu.org/software/make/).

## Running the tests

As [above](#dependencies), you need [Hoverfly](https://hoverfly.readthedocs.io) to run the tests.

Run the tests:

`go test -v .`
`go test ./... -v`

Running the tests in GitHub Enterprise Cloud mode (verifying that the label checker
works properly on [GitHub Enterprise Cloud](https://docs.github.com/en/get-started/onboarding/getting-started-with-github-enterprise-cloud)):

`go test -enterprise-cloud -v .`
`go test ./... -enterprise-cloud -v`

Running the tests in Github Enterprise Server mode (verifying that the label checker
works properly on [GitHub Enterprise Server](https://docs.github.com/en/enterprise-server/admin/overview/about-github-enterprise-server)):

`go test -enterprise-server -v .`
`go test ./... -enterprise-server -v`

The tests are [table driven](https://dave.cheney.net/2019/05/07/prefer-table-driven-tests), which is an important concept to know when amending them.

The tests also have an integration mode which makes calls to real external services instead of using Hoverfly to virtualise the service calls. You do not need to run the tests in integration mode when contributing (they will not pass unless you are a [maintainer](.github/CODEOWNERS) of the project who has the designated GitHub permissions).

If you are a maintainer, and you want to run the integration tests locally, you will need to set the `INPUT_REPO_TOKEN` environment variable, e.g. if using a VS Code Codespace you can run:

`INPUT_REPO_TOKEN=$GITHUB_TOKEN go test -integration -v .`
`INPUT_REPO_TOKEN=$GITHUB_TOKEN go test ./... -integration -v`

You can also run the integration tests locally in GitHub Enterprise Cloud mode:

`INPUT_REPO_TOKEN=$GITHUB_TOKEN go test -integration -enterprise-cloud -v .`
`INPUT_REPO_TOKEN=$GITHUB_TOKEN go test ./... -integration -enterprise-cloud -v`

(we can't run the integration tests in GitHub Enterprise Server mode as that would require having
a real GitHub Enterprise Server, which would be expensive in time and money to maintain)
Expand Down
3 changes: 1 addition & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ FROM golang:1.16.6-buster AS builder
WORKDIR /src
COPY . .

RUN scripts/install-mage.sh \
&& CGO_ENABLED=0 GOFLAGS=-ldflags="-w" mage -compile /bin/check-labels -goos linux -goarch amd64 \
RUN CGO_ENABLED=0 GOFLAGS=-ldflags="-w" GOOS=linux GOARCH=amd64 go build -o /bin/check-labels label_checker.go \
# Strip any symbols - this is not a library
&& strip /bin/check-labels \
# Compress the compiled action using UPX (https://upx.github.io/)
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
)](https://github.com/agilepathway/label-checker/releases)

[![License](https://img.shields.io/badge/license-MIT-blue.svg?maxAge=43200)](LICENSE)
[![Built with Mage](https://magefile.org/badge.svg)](https://magefile.org)
[![Go Report Card](https://goreportcard.com/badge/github.com/agilepathway/label-checker)](https://goreportcard.com/report/github.com/agilepathway/label-checker)
[![Go version](https://img.shields.io/github/go-mod/go-version/agilepathway/label-checker)](https://golang.org/)

Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ module github.com/agilepathway/label-checker
go 1.16

require (
github.com/magefile/mage v1.13.0
github.com/shurcooL/githubv4 v0.0.0-20200414012201-bbc966b061dd
github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f // indirect
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/magefile/mage v1.13.0 h1:XtLJl8bcCM7EFoO8FyH8XK3t7G5hQAeK+i4tq+veT9M=
github.com/magefile/mage v1.13.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
github.com/shurcooL/githubv4 v0.0.0-20200414012201-bbc966b061dd h1:EwtC+kDj8s9OKiaStPZtTv3neldOyr98AXIxvmn3Gss=
github.com/shurcooL/githubv4 v0.0.0-20200414012201-bbc966b061dd/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo=
github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f h1:tygelZueB1EtXkPI6mQ4o9DQ0+FKW41hTbunoXZCTqk=
Expand Down
31 changes: 18 additions & 13 deletions internal/github/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
Expand All @@ -18,13 +19,19 @@ import (

// Action encapsulates the Label Checker GitHub Action
type Action struct {
Stdout io.Writer // writer to write stdout messages to
Stderr io.Writer // writer to write stderr messages to
successMsg string
failMsg string
}

// CheckLabels checks pull requests for the presence or absence of specified GitHub labels
func (a *Action) CheckLabels() error {
fmt.Println("Checking GitHub labels ...")
// CheckLabels checks pull requests for the specified GitHub labels.
// It returns the exit code that callers should exit with - 0 if the
// checks were successful and 1 if they failed.
func (a *Action) CheckLabels(stdout, stderr io.Writer) int {
a.Stdout = stdout
a.Stderr = stderr
fmt.Fprintln(a.Stdout, "Checking GitHub labels ...")

pr := pullrequest.New(
a.repositoryOwner(),
Expand All @@ -40,29 +47,27 @@ func (a *Action) CheckLabels() error {
a.runCheck(pr.Labels.HasAnyOf, a.anyRequired)

if len(a.successMsg) > 0 {
fmt.Println(a.trimTrailingNewLine(a.successMsg))
fmt.Fprintln(a.Stdout, a.trimTrailingNewLine(a.successMsg))
}

if len(a.failMsg) > 0 {
return a.handleFailure()
}

a.outputResult("success")

return nil
return 0
}

func (a *Action) handleFailure() error {
// handleFailure returns the exit code status for the
// GitHub Action in the event of the label checks failing.
func (a *Action) handleFailure() int {
a.outputResult("failure")
err := errors.New(a.trimTrailingNewLine(a.failMsg))

fmt.Fprintln(a.Stderr, "Error:", err)
if a.allowFailure() {
fmt.Fprintln(os.Stderr, "Error:", err)

return nil
return 0
}

return err
return 1
}

func (a *Action) trimTrailingNewLine(input string) string {
Expand Down
23 changes: 9 additions & 14 deletions label_checker_test.go → internal/github/action_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package test
package github

import (
"bytes"
Expand All @@ -11,7 +11,6 @@ import (
"testing"

"github.com/agilepathway/label-checker/internal/error/panic"
"github.com/magefile/mage/mage"
)

//nolint: gochecknoglobals
Expand Down Expand Up @@ -51,10 +50,9 @@ const (
OneLabelPR = 2 // https://github.com/agilepathway/test-label-checker-consumer/pull/2
TwoLabelsPR = 3 // https://github.com/agilepathway/test-label-checker-consumer/pull/3
ThreeLabelsPR = 4 // https://github.com/agilepathway/test-label-checker-consumer/pull/4
GitHubEventJSONDir = "testdata/temp"
GitHubEventJSONDir = "../../testdata/temp"
GitHubEventJSONFilename = "github_event.json"
GitHubOutputFilename = "github_output"
MagefileVerbose = "MAGEFILE_VERBOSE"
HoverflyProxyAddress = "127.0.0.1:8500"
NeedNoneGotNone = "Label check successful: required none of major, minor, patch, and found 0.\n"
NeedNoneGotOne = "Label check failed: required none of major, minor, patch, but found 1: minor\n"
Expand Down Expand Up @@ -84,8 +82,8 @@ func TestLabelChecks(t *testing.T) {
expectedStdout string
expectedStderr string
}{
"Need none, got none": {NoLabelsPR, checkNone, NeedNoneGotNone, ""},
"Need none, got one": {OneLabelPR, checkNone, "", NeedNoneGotOne},
"Need none, got none": {NoLabelsPR, checkNone, NeedNoneGotNone, ""},
"Need none, got one": {OneLabelPR, checkNone, "", NeedNoneGotOne},
"Need none, got two": {TwoLabelsPR, checkNone, "", NeedNoneGotTwo},
"Need one, got none": {NoLabelsPR, checkOne, "", NeedOneGotNone},
"Need one, got one": {OneLabelPR, checkOne, NeedOneGotOne, ""},
Expand Down Expand Up @@ -121,7 +119,7 @@ func TestLabelChecks(t *testing.T) {
setPullRequestNumber(tc.prNumber)
tc.specifyChecks()

exitCode, stderr, stdout := checkLabels()
exitCode, stdout, stderr := checkLabels()

if (len(tc.expectedStderr) > 0) && (exitCode == 0) {
t.Fatalf("got exit code %v, err: %s", exitCode, stderr)
Expand Down Expand Up @@ -154,7 +152,6 @@ func TestMain(m *testing.M) {
os.Setenv(EnvGitHubRepository, GitHubTestRepo) //nolint
os.Setenv(EnvGitHubEventPath, gitHubEventFullPath()) //nolint
os.Setenv(EnvGitHubOutput, gitHubOutputFullPath()) //nolint
os.Setenv(MagefileVerbose, "1") //nolint
os.Setenv(EnvRequireOneOf, " ") //nolint
os.Setenv(EnvRequireNoneOf, " ") //nolint
os.Setenv(EnvRequireAllOf, " ") //nolint
Expand All @@ -170,7 +167,6 @@ func testMainWrapper(m *testing.M) int {
os.RemoveAll(GitHubEventJSONDir)
os.Unsetenv(EnvGitHubRepository)
os.Unsetenv(EnvGitHubEventPath)
os.Unsetenv(MagefileVerbose)
os.Unsetenv(EnvGitHubEnterprise)
os.Unsetenv(EnvAllowFailure)
teardownVirtualServicesIfNotInIntegrationMode()
Expand Down Expand Up @@ -217,9 +213,9 @@ func startHoverflyInSpyMode() {

func importGitHubSimulations() {
if *enterpriseServer {
execHoverCtl("import", "./testdata/github_enterprise_server_api.json")
execHoverCtl("import", "../../testdata/github_enterprise_server_api.json")
} else {
execHoverCtl("import", "./testdata/github_api.json")
execHoverCtl("import", "../../testdata/github_api.json")
}
}

Expand All @@ -230,9 +226,8 @@ func stopHoverfly() {
func checkLabels() (int, *bytes.Buffer, *bytes.Buffer) {
stdout := &bytes.Buffer{}
stderr := &bytes.Buffer{}
invocation := mage.Invocation{Stderr: stderr, Stdout: stdout}

return mage.Invoke(invocation), stderr, stdout
a := Action{}
return a.CheckLabels(stdout, stderr), stdout, stderr
}

func setPullRequestNumber(prNumber int) {
Expand Down
15 changes: 7 additions & 8 deletions label_checker.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
//go:build mage
// +build mage

//nolint:unused,deadcode,gochecknoglobals
package main

import "github.com/agilepathway/label-checker/internal/github"
import (
"os"

var Default = PullRequestLabelChecker
"github.com/agilepathway/label-checker/internal/github"
)

// PullRequestLabelChecker checks pull requests for the presence or absence of specified GitHub labels
func PullRequestLabelChecker() error {
func main() {
a := github.Action{}
return a.CheckLabels()
exitCode := a.CheckLabels(os.Stdout, os.Stderr)
os.Exit(exitCode)
}
6 changes: 0 additions & 6 deletions scripts/install-mage.sh

This file was deleted.

0 comments on commit 318a78c

Please sign in to comment.