Skip to content

Commit

Permalink
feat(ci): create a CI workflow to build and test code
Browse files Browse the repository at this point in the history
  • Loading branch information
Salaton committed Oct 7, 2022
1 parent 0834430 commit 4287efa
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 39 deletions.
71 changes: 71 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Test

on: [push]

env:
SIL_COMMS_BASE_URL: ${{ secrets.SIL_COMMS_BASE_URL }}
SIL_COMMS_EMAIL: ${{ secrets.SIL_COMMS_EMAIL }}
SIL_COMMS_PASSWORD: ${{ secrets.SIL_COMMS_PASSWORD }}
SIL_COMMS_SENDER_ID: ${{ secrets.SIL_COMMS_SENDER_ID }}

jobs:
lint_and_test:
strategy:
fail-fast: true
matrix:
go-version: [1.17.x]
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v3
- name: Install Golang
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}

- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: v1.29

- name: Install Go dependencies
run: |
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.37.1
go get -u github.com/kisielk/errcheck
go get -u golang.org/x/lint/golint
go get -u honnef.co/go/tools/cmd/staticcheck
go get -u github.com/axw/gocov/gocov
go get -u github.com/securego/gosec/cmd/gosec
go get -u github.com/ory/go-acc
go get -u github.com/client9/misspell/cmd/misspell
go get -u github.com/gordonklaus/ineffassign
go get github.com/fzipp/gocyclo
go get github.com/stretchr/testify/assert@v1.7.0
go get github.com/ory/go-acc
- name: Run lint and test
run: |
staticcheck ./...
go fmt $(go list ./... | grep -v /vendor/)
go vet $(go list ./... | grep -v /vendor/)
golint -set_exit_status $(go list ./... | grep -v /vendor/)
errcheck -ignore 'os:.*,' $(go list ./... | grep -v /vendor/)
misspell -error .
gosec ./...
go-acc -o coverage.txt --ignore generated,cmd ./... -- -timeout 60m
grep -v "generated.go" coverage.txt > coverage.out
go tool cover -html=coverage.out -o coverage.html
gocov convert coverage.out > coverage.json
gocov report coverage.json > coverage_report.txt
tail coverage_report.txt
- name: Install goveralls
env:
GO111MODULE: off
run: go get github.com/mattn/goveralls

- name: Send coverage
env:
COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: goveralls -coverprofile=coverage.out -service=github
55 changes: 28 additions & 27 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,25 @@ import (
)

var (
// COMMS_BASE_URL
COMMS_BASE_URL = serverutils.MustGetEnvVar("SIL_COMMS_BASE_URL")
// commsBaseURL represents the SIL-Comms base URL
commsBaseURL = serverutils.MustGetEnvVar("SIL_COMMS_BASE_URL")

// COMMS_EMAIL
COMMS_EMAIL = serverutils.MustGetEnvVar("SIL_COMMS_EMAIL")
// commsEmail is used for authentication against the SIL comms API
commsEmail = serverutils.MustGetEnvVar("SIL_COMMS_EMAIL")

// COMMS_PASSWORD
COMMS_PASSWORD = serverutils.MustGetEnvVar("SIL_COMMS_PASSWORD")
// commsPassword is used for authentication against the SIL comms API
commsPassword = serverutils.MustGetEnvVar("SIL_COMMS_PASSWORD")

// ACCESS_TOKEN_TIMEOUT
ACCESS_TOKEN_TIMEOUT = 30 * time.Minute
// accessTokenTimeout shows the access token expiry time.
// After the access token expires, one is required to obtain a new one
accessTokenTimeout = 30 * time.Minute

// REFRESH_TOKEN_TIMEOUT
REFRESH_TOKEN_TIMEOUT = 24 * time.Hour
// refreshTokenTimeout shows the refresh token expiry time
refreshTokenTimeout = 24 * time.Hour
)

// SILCommsClient is the client used to make API request to sil communications API
type SILCommsClient struct {
// CommsClient is the client used to make API request to sil communications API
type CommsClient struct {
client http.Client

refreshToken string
Expand All @@ -43,8 +44,8 @@ type SILCommsClient struct {
}

// NewSILCommsClient initializes a new SIL comms client instance
func NewSILCommsClient() *SILCommsClient {
s := &SILCommsClient{
func NewSILCommsClient() *CommsClient {
s := &CommsClient{
client: http.Client{},
accessToken: "",
refreshToken: "",
Expand All @@ -56,7 +57,7 @@ func NewSILCommsClient() *SILCommsClient {
}

// executed as a go routine to update the api tokens when they timeout
func (s *SILCommsClient) background() {
func (s *CommsClient) background() {
for {
select {
case t := <-s.refreshTokenTicker.C:
Expand All @@ -71,34 +72,34 @@ func (s *SILCommsClient) background() {
}
}

func (s *SILCommsClient) setAccessToken(token string) {
func (s *CommsClient) setAccessToken(token string) {
s.accessToken = token
if s.accessTokenTicker != nil {
s.accessTokenTicker.Reset(ACCESS_TOKEN_TIMEOUT)
s.accessTokenTicker.Reset(accessTokenTimeout)
} else {
s.accessTokenTicker = time.NewTicker(ACCESS_TOKEN_TIMEOUT)
s.accessTokenTicker = time.NewTicker(accessTokenTimeout)
}
}

func (s *SILCommsClient) setRefreshToken(token string) {
func (s *CommsClient) setRefreshToken(token string) {
s.refreshToken = token
if s.refreshTokenTicker != nil {
s.refreshTokenTicker.Reset(REFRESH_TOKEN_TIMEOUT)
s.refreshTokenTicker.Reset(refreshTokenTimeout)
} else {
s.refreshTokenTicker = time.NewTicker(REFRESH_TOKEN_TIMEOUT)
s.refreshTokenTicker = time.NewTicker(refreshTokenTimeout)
}
}

// login uses the provided credentials to login to the SIL communications backend
// It obtains the necessary tokens required to make authenticated requests
func (s *SILCommsClient) login() {
func (s *CommsClient) login() {
path := "/auth/token/"
payload := struct {
Email string `json:"email"`
Password string `json:"password"`
}{
Email: COMMS_EMAIL,
Password: COMMS_PASSWORD,
Email: commsEmail,
Password: commsPassword,
}

response, err := s.MakeRequest(context.Background(), http.MethodPost, path, nil, payload, false)
Expand Down Expand Up @@ -131,7 +132,7 @@ func (s *SILCommsClient) login() {

}

func (s *SILCommsClient) refreshAccessToken() {
func (s *CommsClient) refreshAccessToken() {
path := "/auth/token/refresh/"
payload := struct {
Refresh string `json:"refresh"`
Expand Down Expand Up @@ -169,8 +170,8 @@ func (s *SILCommsClient) refreshAccessToken() {
}

// MakeRequest performs a HTTP request to the provided path
func (s *SILCommsClient) MakeRequest(ctx context.Context, method, path string, queryParams map[string]string, body interface{}, authorised bool) (*http.Response, error) {
urlPath := fmt.Sprintf("%s%s", COMMS_BASE_URL, path)
func (s *CommsClient) MakeRequest(ctx context.Context, method, path string, queryParams map[string]string, body interface{}, authorised bool) (*http.Response, error) {
urlPath := fmt.Sprintf("%s%s", commsBaseURL, path)
var request *http.Request

switch method {
Expand Down
6 changes: 3 additions & 3 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func TestSILComms_Login(t *testing.T) {
})
}

s := &SILCommsClient{
s := &CommsClient{
client: tt.fields.client,
}
s.login()
Expand Down Expand Up @@ -83,7 +83,7 @@ func TestSILCommsClient_refreshAccessToken(t *testing.T) {
})
}

s := &SILCommsClient{
s := &CommsClient{
client: tt.fields.client,
refreshToken: tt.fields.refreshToken,
}
Expand Down Expand Up @@ -175,7 +175,7 @@ func TestSILCommsClient_MakeRequest(t *testing.T) {
})
}

s := &SILCommsClient{
s := &CommsClient{
client: tt.fields.client,
accessToken: tt.fields.accessToken,
}
Expand Down
5 changes: 4 additions & 1 deletion enums.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ package silcomms
type Status string

const (
// StatusSuccess ...
StatusSuccess Status = "success"
// StatusFailure ...
StatusFailure Status = "failure"
StatusError Status = "error"
// StatusError ...
StatusError Status = "error"
)

// IsValid returns true if a status is valid
Expand Down
16 changes: 8 additions & 8 deletions sms.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,23 @@ import (
)

var (
// COMMS_SENDER_ID
COMMS_SENDER_ID = serverutils.MustGetEnvVar("SIL_COMMS_SENDER_ID")
// commsSenderID is the ID used to send the SMS
commsSenderID = serverutils.MustGetEnvVar("SIL_COMMS_SENDER_ID")
)

// ICommsClient is the interface for the client to make API request to sil communications
type ICommsClient interface {
MakeRequest(ctx context.Context, method, path string, queryParams map[string]string, body interface{}, authorised bool) (*http.Response, error)
}

// SILCommsLib is the SDK implementation for interacting with the sil communications API
type SILCommsLib struct {
// CommsLib is the SDK implementation for interacting with the sil communications API
type CommsLib struct {
Client ICommsClient
}

// NewSILCommsLib initializes a new implementation of the SIL Comms SDK
func NewSILCommsLib(client ICommsClient) *SILCommsLib {
l := &SILCommsLib{
func NewSILCommsLib(client ICommsClient) *CommsLib {
l := &CommsLib{
Client: client,
}

Expand All @@ -37,14 +37,14 @@ func NewSILCommsLib(client ICommsClient) *SILCommsLib {
// SendBulkSMS returns a 202 Accepted synchronous response while the API attempts to send the SMS in the background.
// An asynchronous call is made to the app's sms_callback URL with a notification that shows the Bulk SMS status.
// An asynchronous call is made to the app's sms_callback individually for each of the recipients with the SMS status.
func (l SILCommsLib) SendBulkSMS(ctx context.Context, message string, recipients []string) (*BulkSMSResponse, error) {
func (l CommsLib) SendBulkSMS(ctx context.Context, message string, recipients []string) (*BulkSMSResponse, error) {
path := "/v1/sms/bulk/"
payload := struct {
Sender string `json:"sender"`
Message string `json:"message"`
Recipients []string `json:"recipients"`
}{
Sender: COMMS_SENDER_ID,
Sender: commsSenderID,
Message: message,
Recipients: recipients,
}
Expand Down

0 comments on commit 4287efa

Please sign in to comment.