Varakh
1fc3818d3c
All checks were successful
/ build (push) Successful in 5m3s
- Switched to enforce JSON as Content-Type for all incoming requests - Switched to properly respond with JSON on page not found or method not allowed - Renamed CORS_ALLOW_ORIGIN to CORS_ALLOW_ORIGINS - Added CORS_ALLOW_CREDENTIALS which defaults to true - Added CORS_EXPOSE_HEADERS which defaults to * - Overhauled package visibility for server module |
||
---|---|---|
.forgejo/workflows | ||
_doc | ||
api | ||
cmd | ||
server | ||
terminal | ||
util | ||
.editorconfig | ||
.gitignore | ||
CHANGELOG.md | ||
Dockerfile | ||
go.mod | ||
go.sum | ||
LICENSE.txt | ||
Makefile | ||
README.md | ||
renovate.json5 |
README
Backend for upda - Update Dashboard in Go.
The main git repository is hosted at https://git.myservermanager.com/varakh/upda. Other repositories are mirrors and pull requests, issues, and planning are managed there.
Contributions are very welcome!
Official documentation is hosted in a separate git repository.
Development & contribution
- Pay attention to
make checkstyle
(usesgo vet ./...
); pipeline fails if issues are detected. - Each entity has its own repository
- Each entity is only used in repository and service (otherwise, mapping happens)
- Presenter layer is constructed from the entity, e.g., in REST responses and mapped
- No entity is directly returned in any REST response
- All log calls should be handled by
zap.L()
- Configuration is bootstrapped via separated
struct
types which are given to the service which need them - Error handling
- Always throw an error with
NewServiceError
for repositories, services and handlers - Always throw an error wrapping the cause with
fmt.Errorf
- Forward/bubble up the error directly, when original error is already a
NewServiceError
(most likely internal calls) - Always abort handler chain with
AbortWithError
- Utils can throw any error
- Repositories, handlers and services should always properly return
error
including anyinit
-like function ( best to avoid them and call innewXXX
). Do not abort withFatalf
or similar log.Fatalf
orzap.L().Fatal
is allowed inenvironment.go
orapp.go
- Always throw an error with
- Look into the
_doc/
folder for OpenAPI specification and a Postman Collection. - Consider reading Effective Go
- Consider reading 100 Go Mistakes and How to Avoid Them
Getting started
Ensure to set the following environment variables for proper debug logs during development
DEVELOPMENT=true
LOGGING_ENCODING=console
LOGGING_LEVEL=debug
- Run
make clean dependencies
to fetch dependencies - Start
git.myservermanager.com/varakh/upda/cmd/server
(orcli
) as Go application and ensure to have required environment variables set
If you like to test with PSQL and/or REDIS for task locking, here are some useful docker commands to have containers up and running quickly. Set necessary environment variables properly.
# postgres
docker run --rm --name=upda-db \
-p 5432:5432 \
--restart=unless-stopped \
-e POSTGRES_USER=upda \
-e POSTGRES_PASSWORD=upda \
-e POSTGRES_DB=upda \
postgres:16-alpine
# redis
docker run --rm --name some-redis \
-p 6379:6379 \
redis redis-server --save 60 1 --loglevel warning
Windows hints
On Windows, you need a valid gcc
, e.g., https://jmeubank.github.io/tdm-gcc/download/ and add the \bin
folder to your
path.
For any go
command you run, ensure that your PATH
has the gcc
binary and that you add CGO_ENABLED=1
as
environment.
Using the lockService
correctly
The lockService
can be used to lock resources. This works in-memory and also in a distributed fashion with REDIS.
Ensure to provide proper locking options when using, although in-memory ignores those.
Example:
# invoked from an endpoint
context := c.Request.Context()
var err error
var lock appLock
if lock, err = h.lockService.lockWithOptions(context, "TEST-LOCK", withAppLockOptionExpiry(5*time.Minute), withAppLockOptionInfiniteRetries(), withAppLockOptionRetryDelay(5*time.Second)); err != nil {
_ = c.AbortWithError(errToHttpStatus(err), err)
return
}
# defer to avoid leakage
defer func(lock appLock) {
_ = lock.unlock(context)
}(lock)
# simulate long running task
time.Sleep(20 * time.Second)
Release
Releases are handled by the SCM platform and pipeline. Creating a new git tag, creates a new release in the SCM
platform, uploads produced artifacts to that release and publishes docker images automatically.
Before doing so, please ensure that the commit on master
has the correct version settings and has been
built successfully:
- Adapt
constants_app.go
and changeVersion
to the correct version number - Adapt
app.go
and changeversion
to the correct version number (CLI) - Adapt
CHANGELOG.md
to reflect changes and ensure a date is properly set in the header, also add a reference link in footer (link to scm git tag source) - Adapt
api.yaml
:version
attribute must reflect the to be released version - Adapt
env: VERSION_*
in.forgejo/workflows/release.yaml
After the release has been created, ensure to change the following settings for the next development cycle:
- Adapt
constants_app.go
and changeVersion
to the next version number - Adapt
app.go
and changeversion
to the next version number (CLI) - Adapt
CHANGELOG.md
and add an UNRELEASED section - Adapt
api.yaml
:version
attribute must reflect the next version number - Adapt
env: VERSION_*
in.forgejo/workflows/release.yaml
to next version number