Skip to content

Commit

Permalink
Use GitHub Actions (#442)
Browse files Browse the repository at this point in the history
Add lint, build (multi-platform), and test (linux-only) GitHub Actions. Fix
a variety of golangci-lint findings.

For now, does not modify the windows Appveyor setup, and does not
run the loadtester.

Fixes #356
  • Loading branch information
ldez authored Feb 27, 2024
1 parent 08999ce commit 5b7dc87
Show file tree
Hide file tree
Showing 15 changed files with 416 additions and 194 deletions.
53 changes: 53 additions & 0 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Checks

on:
push:
branches:
- main
pull_request:

permissions:
contents: read
pull-requests: read

jobs:

checks:
name: Check Process
runs-on: ubuntu-latest
env:
GO_VERSION: oldstable
GOLANGCI_LINT_VERSION: v1.56.2
CGO_ENABLED: 0

steps:

- name: Check out code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}

- name: Check and get dependencies
run: |
go mod tidy
git diff --exit-code go.mod
git diff --exit-code go.sum
- name: vendoring
run: go mod vendor

- name: vendoring diff
run: git diff --exit-code vendor/

# https://golangci-lint.run/usage/install#other-ci
- name: Install golangci-lint ${{ env.GOLANGCI_LINT_VERSION }}
run: |
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin ${GOLANGCI_LINT_VERSION}
golangci-lint run
38 changes: 38 additions & 0 deletions .github/workflows/go-cross.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Go Matrix
on:
push:
branches:
- main
pull_request:

permissions:
contents: read
pull-requests: read

jobs:

cross:
name: Build
runs-on: ${{ matrix.os }}
env:
CGO_ENABLED: 0

strategy:
matrix:
go-version: [ oldstable, stable ]
os: [ubuntu-latest, macos-latest, windows-latest]

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}

- name: Build pebble
run: go build -v -ldflags "-s -w" -trimpath -o pebble ./cmd/pebble

- name: Build pebble-challtestsrv
run: go build -v -ldflags "-s -w" -trimpath -o pebble-challtestsrv ./cmd/pebble-challtestsrv
70 changes: 70 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Tests

on:
push:
branches:
- main
pull_request:

permissions:
contents: read
pull-requests: read

jobs:

test-linux:
name: Test on Linux
runs-on: ubuntu-latest
env:
GO_VERSION: oldstable
steps:

- name: Setup /etc/hosts
run: |
echo "127.0.0.1 example.letsencrypt.org" | sudo tee -a /etc/hosts
echo "127.0.0.1 elpmaxe.letsencrypt.org" | sudo tee -a /etc/hosts
# https://github.com/marketplace/actions/checkout
- name: Check out code
uses: actions/checkout@v4
with:
fetch-depth: 0

# https://github.com/marketplace/actions/setup-go-environment
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}

- name: apt install
run: sudo apt-get install snapd python3-acme python3-josepy

- name: snap install
run: sudo snap install core && sudo snap refresh core

- name: snap install certbot
run: sudo snap install --classic certbot && sudo ln -s /snap/bin/certbot /usr/bin/certbot

- name: go install tools
run: go install golang.org/x/tools/cmd/cover@latest

- name: go install goveralls
run: go install github.com/mattn/goveralls@latest

- name: go install pebble
run: go install -v -race ./...

- name: launch pebble
run: GORACE="halt_on_error=1" PEBBLE_WFE_NONCEREJECT=0 pebble &

# Run project unit tests (with the race detector enabled and atomic coverage profile collection)
- name: unittests
run: go test -v -race -covermode=atomic -coverprofile=coverage.out ./...

# # Upload collected coverage profile to goveralls
# - name: goveralls
# run: goveralls -coverprofile=coverage.out -service=github

# Perform a test issuance with chisel2.py
- name: chisel
run: REQUESTS_CA_BUNDLE=./test/certs/pebble.minica.pem python ./test/chisel2.py example.letsencrypt.org elpmaxe.letsencrypt.org
94 changes: 67 additions & 27 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,79 @@ linters-settings:
locale: "US"

linters:
enable-all: true
disable:
- stylecheck
- gosec
- dupl
- maligned
- depguard
- lll
- prealloc
- scopelint
- gocritic
- gochecknoinits
- gochecknoglobals
- godox
- funlen
- wsl
- whitespace
- gomnd
- typecheck
- godot
- errname
- nlreturn
- wrapcheck
disable-all: false
enable:
- asasalint
- asciicheck
- bidichk
- bodyclose
- containedctx
- decorder
- dogsled
- dupword
- durationcheck
- errcheck
- errchkjson
- errorlint
- exportloopref
- forcetypeassert
- ginkgolinter
- gocheckcompilerdirectives
- gocognit
- goconst
- gocyclo
- gofmt
- gofumpt
- goheader
- goimports
- gomoddirectives
- gomodguard
- goprintffuncname
- gosimple
- govet
- importas
- inamedparam
- ineffassign
- ireturn
- loggercheck
- makezero
- mirror
- misspell
- nakedret
- nolintlint
- nonamedreturns
- nosprintfhostport
- perfsprint
- predeclared
- reassign
- revive
- staticcheck
- tagalign
- tenv
- testableexamples
- testifylint
- thelper
- unconvert
- unparam
- unused
- usestdlibvars
- wastedassign

issues:
exclude-use-default: true
max-per-linter: 0
max-issues-per-linter: 0
max-same-issues: 0
# The following excludes are considered false-positives/known-OK.
exclude:
- fmt.Sprintf can be replaced with string
exclude-rules:
- path: ca([/|\\])ca.go
- path: ca/ca.go
text: 'type name will be used as ca.CAImpl by other packages, and that stutters; consider calling this Impl'
- path: va([/|\\])va.go
- path: va/va.go
text: 'type name will be used as va.VAImpl by other packages, and that stutters; consider calling this Impl'
- path: wfe([/|\\])wfe.go
- path: wfe/wfe.go
text: 'if` block ends with a `return` statement, so drop this `else` and outdent its block'
- path: va/va.go
linters:
- goconst
text: 'string `Incorrect validation certificate for %s challenge. ` has \d occurrences, make it a constant'
13 changes: 7 additions & 6 deletions ca/ca.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"crypto/x509/pkix"
"encoding/asn1"
"encoding/hex"
"errors"
"fmt"
"log"
"math"
Expand Down Expand Up @@ -110,8 +111,8 @@ func (ca *CAImpl) makeRootCert(
subjectKey crypto.Signer,
subject pkix.Name,
subjectKeyID []byte,
signer *issuer) (*core.Certificate, error) {

signer *issuer,
) (*core.Certificate, error) {
serial := makeSerial()
template := &x509.Certificate{
Subject: subject,
Expand Down Expand Up @@ -187,7 +188,7 @@ func (ca *CAImpl) newRootIssuer(name string) (*issuer, error) {

func (ca *CAImpl) newIntermediateIssuer(root *issuer, intermediateKey crypto.Signer, subject pkix.Name, subjectKeyID []byte) (*issuer, error) {
if root == nil {
return nil, fmt.Errorf("Internal error: root must not be nil")
return nil, errors.New("internal error: root must not be nil")
}
// Make an intermediate certificate with the root issuer
ic, err := ca.makeRootCert(intermediateKey, subject, subjectKeyID, root)
Expand Down Expand Up @@ -253,12 +254,12 @@ func (ca *CAImpl) newChain(intermediateKey crypto.Signer, intermediateSubject pk

func (ca *CAImpl) newCertificate(domains []string, ips []net.IP, key crypto.PublicKey, accountID, notBefore, notAfter string) (*core.Certificate, error) {
if len(domains) == 0 && len(ips) == 0 {
return nil, fmt.Errorf("must specify at least one domain name or IP address")
return nil, errors.New("must specify at least one domain name or IP address")
}

defaultChain := ca.chains[0].intermediates
if len(defaultChain) == 0 || defaultChain[0].cert == nil {
return nil, fmt.Errorf("cannot sign certificate - nil issuer")
return nil, errors.New("cannot sign certificate - nil issuer")
}
issuer := defaultChain[0]

Expand Down Expand Up @@ -443,7 +444,7 @@ func (ca *CAImpl) GetRootKey(no int) *rsa.PrivateKey {
return nil
}

// GetIntermediateCert returns the first (closest the the leaf) issuer certificate
// GetIntermediateCert returns the first (closest the leaf) issuer certificate
// in the chain identified by `no`.
func (ca *CAImpl) GetIntermediateCert(no int) *core.Certificate {
chain := ca.getChain(no)
Expand Down
3 changes: 2 additions & 1 deletion cmd/pebble-challtestsrv/history.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ func requestHost(r *http.Request) (string, error) {
// writeHistory writes the provided list of challtestsrv.RequestEvents to the
// provided http.ResponseWriter in JSON form.
func (srv *managementServer) writeHistory(
history []challtestsrv.RequestEvent, w http.ResponseWriter) {
history []challtestsrv.RequestEvent, w http.ResponseWriter,
) {
// Always write an empty JSON list instead of `null`
if history == nil {
history = []challtestsrv.RequestEvent{}
Expand Down
10 changes: 6 additions & 4 deletions cmd/pebble-challtestsrv/httpone.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import "net/http"
//
// The POST body is expected to have two non-empty parameters:
// "token" - the HTTP-01 challenge token to add the mock HTTP-01 response under
// in the `/.well-known/acme-challenge/` path.
// in the `/.well-known/acme-challenge/` path.
//
// "content" - the key authorization value to return in the HTTP response.
//
// A successful POST will write http.StatusOK to the client.
Expand Down Expand Up @@ -40,7 +41,7 @@ func (srv *managementServer) addHTTP01(w http.ResponseWriter, r *http.Request) {
//
// The POST body is expected to have one non-empty parameter:
// "token" - the HTTP-01 challenge token to remove the mock HTTP-01 response
// from.
// from.
//
// A successful POST will write http.StatusOK to the client.
func (srv *managementServer) delHTTP01(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -70,9 +71,10 @@ func (srv *managementServer) delHTTP01(w http.ResponseWriter, r *http.Request) {
//
// The POST body is expected to have two non-empty parameters:
// "path" - the path that when matched in an HTTP request will return the
// redirect.
// redirect.
//
// "targetURL" - the URL that the client will be redirected to when making HTTP
// requests for the redirected path.
// requests for the redirected path.
//
// A successful POST will write http.StatusOK to the client.
func (srv *managementServer) addHTTPRedirect(w http.ResponseWriter, r *http.Request) {
Expand Down
Loading

0 comments on commit 5b7dc87

Please sign in to comment.