Compare commits

...

12 Commits

Author SHA1 Message Date
7adc0c9c08 fix: Dockerfile to include .env
Some checks failed
release / docker (push) Has been cancelled
2024-11-19 17:25:20 +03:00
0a19a6c48b fix: github ci spec
Some checks failed
release / docker (push) Has been cancelled
2024-11-19 17:18:13 +03:00
66b5843b0d feat: dockerfile and github based CI build for Africastalking variant (#174)
## Summary

* fixed missing error handler in main
* add injectable build string in main
* add (dynamically linked) docker build
* add github CI workflow
* add extra but useful dev files in dev folder

* closes #93

## Notes

* We'll move to a self-hosted CI runner once it is installed on Gitea.

Reviewed-on: #174
Co-authored-by: Mohammed Sohail <sohailsameja@gmail.com>
Co-committed-by: Mohammed Sohail <sohailsameja@gmail.com>
2024-11-19 15:15:24 +01:00
carlos
109a2a2020 Merge pull request 'menu-balances' (#173) from menu-balances into master
Reviewed-on: #173
Reviewed-by: Alfred Kamanda <alfredkamandamw@gmail.com>
2024-11-19 08:18:43 +01:00
alfred-mk
bc6d8098f3 updated the failed test 2024-11-19 10:15:34 +03:00
Carlosokumu
01e75e9217 update test 2024-11-18 17:30:34 +03:00
Carlosokumu
f2b17880ba check community and my balance separately 2024-11-18 17:30:09 +03:00
Carlosokumu
1d4f116079 community balance str 2024-11-18 17:23:59 +03:00
Carlosokumu
44c52b6ed7 rename fetch_custodial_balances -> fetch_community_balance 2024-11-18 17:23:36 +03:00
Carlosokumu
454f67b317 show balance based on current voucher 2024-11-18 17:21:04 +03:00
Carlosokumu
e1506a3dcf show a placehlolder community balance 2024-11-18 17:20:12 +03:00
carlos
b22a4adec1 Merge pull request 'updated send node' (#172) from send-node into master
Reviewed-on: #172
2024-11-18 14:19:42 +01:00
17 changed files with 177 additions and 77 deletions

13
.dockerignore Normal file
View File

@@ -0,0 +1,13 @@
/**
!/cmd/africastalking
!/common
!/config
!/initializers
!/internal
!/models
!/remote
!/services
!/LICENSE
!/README.md
!/go.*
!/.env.example

56
.github/workflows/docker.yaml vendored Normal file
View File

@@ -0,0 +1,56 @@
name: release
on:
push:
tags:
- "v*"
jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Check out repo
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Cache Docker layers
uses: actions/cache@v3
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Login to GHCR Docker registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set outputs
run: |
echo "RELEASE_TAG=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV \
&& echo "RELEASE_SHORT_COMMIT=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
- name: Build and push image
uses: docker/build-push-action@v2
with:
context: ./
file: ./Dockerfile
platforms: linux/amd64
push: true
build-args: |
BUILD=${{ env.RELEASE_SHORT_COMMIT }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
tags: |
ghcr.io/grassrootseconomics/urdt-ussd:latest
ghcr.io/grassrootseconomics/urdt-ussd:${{ env.RELEASE_TAG }}

41
Dockerfile Normal file
View File

@@ -0,0 +1,41 @@
FROM golang:1.23.0-bookworm AS build
ENV CGO_ENABLED=1
ARG BUILDPLATFORM
ARG TARGETPLATFORM
ARG BUILD=dev
WORKDIR /build
COPY . .
RUN apt update && apt install libgdbm-dev
RUN git clone https://git.defalsify.org/vise.git go-vise
WORKDIR /build/services/registration
RUN echo "Compiling go-vise files"
RUN make VISE_PATH=/build/go-vise -B
WORKDIR /build
RUN echo "Building on $BUILDPLATFORM, building for $TARGETPLATFORM"
RUN go mod download
RUN go build -o ussd-africastalking -ldflags="-X main.build=${BUILD} -s -w" cmd/africastalking/main.go
FROM debian:bookworm-slim
ENV DEBIAN_FRONTEND=noninteractive
RUN apt update && apt install libgdbm-dev ca-certificates -y
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
WORKDIR /service
COPY --from=build /build/ussd-africastalking .
COPY --from=build /build/LICENSE .
COPY --from=build /build/README.md .
COPY --from=build /build/services ./services
COPY --from=build /build/.env.example .
RUN mv .env.example .env
EXPOSE 7123
CMD ["./ussd-africastalking"]

View File

@@ -29,8 +29,10 @@ import (
)
var (
logg = logging.NewVanilla()
scriptDir = path.Join("services", "registration")
logg = logging.NewVanilla()
scriptDir = path.Join("services", "registration")
build = "dev"
)
func init() {
@@ -115,7 +117,7 @@ func main() {
flag.UintVar(&port, "p", initializers.GetEnvUint("PORT", 7123), "http port")
flag.Parse()
logg.Infof("start command", "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size)
logg.Infof("start command", "build", build, "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size)
ctx := context.Background()
ctx = context.WithValue(ctx, "Database", database)
@@ -157,6 +159,10 @@ func main() {
}
lhs, err := handlers.NewLocalHandlerService(ctx, pfp, true, dbResource, cfg, rs)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
lhs.SetDataStore(&userdataStore)
if err != nil {

View File

@@ -0,0 +1,3 @@
url: http://localhost:7123
dial: "*384*96#"
phoneNumber: +254722123456

21
dev/docker-compose.yaml Normal file
View File

@@ -0,0 +1,21 @@
services:
ussd-pg-store:
image: postgres:17-alpine
restart: unless-stopped
user: postgres
environment:
- POSTGRES_PASSWORD=postgres
- POSTGRES_USER=postgres
volumes:
- ./init_db.sql:/docker-entrypoint-initdb.d/init_db.sql
- ussd-pg:/var/lib/postgresql/data
ports:
- "127.0.0.1:5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready"]
interval: 10s
timeout: 5s
retries: 5
volumes:
ussd-pg:
driver: local

1
dev/init_db.sql Normal file
View File

@@ -0,0 +1 @@
CREATE DATABASE urdt_ussd;

View File

@@ -103,7 +103,7 @@ func (ls *LocalHandlerService) GetHandler(accountService remote.AccountServiceIn
ls.DbRs.AddLocalFunc("verify_new_pin", ussdHandlers.VerifyNewPin)
ls.DbRs.AddLocalFunc("confirm_pin_change", ussdHandlers.ConfirmPinChange)
ls.DbRs.AddLocalFunc("quit_with_help", ussdHandlers.QuitWithHelp)
ls.DbRs.AddLocalFunc("fetch_custodial_balances", ussdHandlers.FetchCustodialBalances)
ls.DbRs.AddLocalFunc("fetch_community_balance", ussdHandlers.FetchCommunityBalance)
ls.DbRs.AddLocalFunc("set_default_voucher", ussdHandlers.SetDefaultVoucher)
ls.DbRs.AddLocalFunc("check_vouchers", ussdHandlers.CheckVouchers)
ls.DbRs.AddLocalFunc("get_vouchers", ussdHandlers.GetVoucherList)

View File

@@ -822,42 +822,14 @@ func (h *Handlers) CheckBalance(ctx context.Context, sym string, input []byte) (
return res, nil
}
func (h *Handlers) FetchCustodialBalances(ctx context.Context, sym string, input []byte) (resource.Result, error) {
func (h *Handlers) FetchCommunityBalance(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result
flag_api_error, _ := h.flagManager.GetFlag("flag_api_call_error")
sessionId, ok := ctx.Value("SessionId").(string)
if !ok {
return res, fmt.Errorf("missing session")
}
symbol, _ := h.st.Where()
balanceType := strings.Split(symbol, "_")[0]
store := h.userdataStore
publicKey, err := store.ReadEntry(ctx, sessionId, common.DATA_PUBLIC_KEY)
if err != nil {
logg.ErrorCtxf(ctx, "failed to read publicKey entry with", "key", common.DATA_PUBLIC_KEY, "error", err)
return res, err
}
balanceResponse, err := h.accountService.CheckBalance(ctx, string(publicKey))
if err != nil {
res.FlagSet = append(res.FlagSet, flag_api_error)
return res, nil
}
res.FlagReset = append(res.FlagReset, flag_api_error)
balance := balanceResponse.Balance
switch balanceType {
case "my":
res.Content = fmt.Sprintf("Your balance is %s", balance)
case "community":
res.Content = fmt.Sprintf("Your community balance is %s", balance)
default:
break
}
code := codeFromCtx(ctx)
l := gotext.NewLocale(translationDir, code)
l.AddDomain("default")
//TODO:
//Check if the address is a community account,if then,get the actual balance
res.Content = l.Get("Community Balance: 0.00")
return res, nil
}

View File

@@ -2,7 +2,6 @@ package ussd
import (
"context"
"encoding/json"
"fmt"
"log"
"path"
@@ -1773,58 +1772,43 @@ func TestConfirmPin(t *testing.T) {
}
}
func TestFetchCustodialBalances(t *testing.T) {
fm, err := NewFlagManager(flagsPath)
if err != nil {
t.Logf(err.Error())
}
flag_api_error, _ := fm.GetFlag("flag_api_call_error")
func TestFetchCommunityBalance(t *testing.T) {
// Define test data
sessionId := "session123"
publicKey := "0X13242618721"
ctx, store := InitializeTestStore(t)
ctx = context.WithValue(ctx, "SessionId", sessionId)
err = store.WriteEntry(ctx, sessionId, common.DATA_PUBLIC_KEY, []byte(publicKey))
if err != nil {
t.Fatal(err)
}
tests := []struct {
name string
balanceResponse *models.BalanceResult
expectedResult resource.Result
name string
languageCode string
expectedResult resource.Result
}{
{
name: "Test when fetch custodial balances is not a success",
balanceResponse: &models.BalanceResult{
Balance: "0.003 CELO",
Nonce: json.Number("0"),
},
name: "Test community balance content when language is english",
expectedResult: resource.Result{
FlagReset: []uint32{flag_api_error},
Content: "Community Balance: 0.00",
},
languageCode: "eng",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
mockAccountService := new(mocks.MockAccountService)
mockState := state.NewState(16)
h := &Handlers{
userdataStore: store,
flagManager: fm.parser,
st: mockState,
accountService: mockAccountService,
}
// Set up the expected behavior of the mock
mockAccountService.On("CheckBalance", string(publicKey)).Return(tt.balanceResponse, nil)
ctx = context.WithValue(ctx, "SessionId", sessionId)
ctx = context.WithValue(ctx, "Language", lang.Language{
Code: tt.languageCode,
})
// Call the method
res, _ := h.FetchCustodialBalances(ctx, "fetch_custodial_balances", []byte(""))
res, _ := h.FetchCommunityBalance(ctx, "fetch_community_balance", []byte(""))
//Assert that the result set to content is what was expected
assert.Equal(t, res, tt.expectedResult, "Result should match expected result")

View File

@@ -103,7 +103,7 @@
},
{
"input": "1234",
"expectedContent": "Your balance is 0.003 CELO\n0:Back\n9:Quit"
"expectedContent": "Balance: {balance}\n\n0:Back\n9:Quit"
},
{
"input": "0",
@@ -149,7 +149,7 @@
},
{
"input": "1234",
"expectedContent": "Your community balance is 0.003 CELO\n0:Back\n9:Quit"
"expectedContent": "{balance}\n0:Back\n9:Quit"
},
{
"input": "0",

View File

@@ -1 +1 @@
Salio la kikundi
{{.fetch_community_balance}}

View File

@@ -1 +1 @@
{{.fetch_custodial_balances}}
{{.fetch_community_balance}}

View File

@@ -1,7 +1,7 @@
LOAD reset_incorrect 6
LOAD fetch_custodial_balances 0
LOAD fetch_community_balance 0
CATCH api_failure flag_api_call_error 1
MAP fetch_custodial_balances
MAP fetch_community_balance
CATCH incorrect_pin flag_incorrect_pin 1
CATCH pin_entry flag_account_authorized 0
MOUT back 0

View File

@@ -21,3 +21,6 @@ msgstr "Ombi lako la kumwalika %s kwa matandao wa Sarafu limetumwa."
msgid "Your request failed. Please try again later."
msgstr "Ombi lako halikufaulu. Tafadhali jaribu tena baadaye."
msgid "Community Balance: 0.00"
msgid "Salio la Kikundi: 0.00"

View File

@@ -1 +1 @@
{{.fetch_custodial_balances}}
{{.check_balance}}

View File

@@ -1,7 +1,7 @@
LOAD reset_incorrect 6
LOAD fetch_custodial_balances 0
LOAD check_balance 0
CATCH api_failure flag_api_call_error 1
MAP fetch_custodial_balances
MAP check_balance
CATCH incorrect_pin flag_incorrect_pin 1
CATCH pin_entry flag_account_authorized 0
MOUT back 0