forked from vikunja/vikunja
Compare commits
13 Commits
renovate/g
...
main
Author | SHA1 | Date |
---|---|---|
Yurii Vlasov | 95e2f1c85d | |
Yurii Vlasov | be7dbf9997 | |
Yurii Vlasov | 92cf9b9341 | |
Yurii Vlasov | eb9b1b47fc | |
clos | f660badc3d | |
kolaente | 491a142378 | |
kolaente | 46b261c9fe | |
Yurii Vlasov | d23f9190c3 | |
Yurii Vlasov | aaaa50a75a | |
kolaente | 40411e4100 | |
renovate | f2b4e9260b | |
kolaente | 682123a9c9 | |
renovate | 0cd9cd324e |
|
@ -506,7 +506,7 @@ steps:
|
|||
|
||||
# Build os packages and push it to our bucket
|
||||
- name: build-os-packages-unstable
|
||||
image: goreleaser/nfpm:v2.23.0
|
||||
image: goreleaser/nfpm:v2.24.0
|
||||
pull: always
|
||||
commands:
|
||||
- apk add git go
|
||||
|
@ -522,7 +522,7 @@ steps:
|
|||
depends_on: [ after-build-compress ]
|
||||
|
||||
- name: build-os-packages-version
|
||||
image: goreleaser/nfpm:v2.23.0
|
||||
image: goreleaser/nfpm:v2.24.0
|
||||
pull: always
|
||||
commands:
|
||||
- apk add git go
|
||||
|
@ -731,6 +731,6 @@ steps:
|
|||
- failure
|
||||
---
|
||||
kind: signature
|
||||
hmac: 148171b051fff279f249608111b56ef0fb5a09a8944ce7aee3e3cf7cf5b6fe4a
|
||||
hmac: 8255925defaacaa9e67871cf8376628925da0ff0996752b71bb6c3c2c5e9b8eb
|
||||
|
||||
...
|
||||
|
|
56
Dockerfile
56
Dockerfile
|
@ -1,51 +1,39 @@
|
|||
# syntax=docker/dockerfile:1
|
||||
# ┬─┐┬ ┐o┬ ┬─┐
|
||||
# │─││ │││ │ │
|
||||
# ┘─┘┘─┘┘┘─┘┘─┘
|
||||
|
||||
##############
|
||||
# Build stage
|
||||
FROM --platform=$BUILDPLATFORM techknowlogick/xgo:go-1.19.2 AS build-env
|
||||
FROM techknowlogick/xgo:go-1.19.2 AS builder
|
||||
|
||||
RUN \
|
||||
go install github.com/magefile/mage@latest && \
|
||||
mv /go/bin/mage /usr/local/go/bin
|
||||
RUN go install github.com/magefile/mage@latest && \
|
||||
mv /go/bin/mage /usr/local/go/bin
|
||||
|
||||
ARG VIKUNJA_VERSION
|
||||
|
||||
# Setup repo
|
||||
COPY . /go/src/code.vikunja.io/api
|
||||
WORKDIR /go/src/code.vikunja.io/api
|
||||
COPY . ./
|
||||
|
||||
ARG TARGETOS TARGETARCH TARGETVARIANT
|
||||
# Checkout version if set
|
||||
RUN if [ -n "${VIKUNJA_VERSION}" ]; then git checkout "${VIKUNJA_VERSION}"; fi && \
|
||||
mage build:clean && \
|
||||
mage release:xgo $TARGETOS/$TARGETARCH/$TARGETVARIANT
|
||||
|
||||
###################
|
||||
RUN mage build:clean && \
|
||||
mage release:xgo "${TARGETOS}/${TARGETARCH}/${TARGETVARIANT}"
|
||||
|
||||
# ┬─┐┬ ┐┌┐┐┌┐┐┬─┐┬─┐
|
||||
# │┬┘│ │││││││├─ │┬┘
|
||||
# ┘└┘┘─┘┘└┘┘└┘┴─┘┘└┘
|
||||
|
||||
# The actual image
|
||||
# Note: I wanted to use the scratch image here, but unfortunatly the go-sqlite bindings require cgo and
|
||||
# because of this, the container would not start when I compiled the image without cgo.
|
||||
FROM alpine:3.16
|
||||
FROM alpine:3.16 AS runner
|
||||
LABEL maintainer="maintainers@vikunja.io"
|
||||
WORKDIR /app/vikunja
|
||||
ENTRYPOINT [ "/sbin/tini", "-g", "--", "/entrypoint.sh" ]
|
||||
|
||||
WORKDIR /app/vikunja/
|
||||
COPY --from=build-env /build/vikunja-* vikunja
|
||||
ENV VIKUNJA_SERVICE_ROOTPATH=/app/vikunja/
|
||||
|
||||
# Dynamic permission changing stuff
|
||||
ENV PUID 1000
|
||||
ENV PGID 1000
|
||||
RUN apk --no-cache add shadow && \
|
||||
addgroup -g ${PGID} vikunja && \
|
||||
adduser -s /bin/sh -D -G vikunja -u ${PUID} vikunja -h /app/vikunja -H && \
|
||||
chown vikunja -R /app/vikunja
|
||||
COPY run.sh /run.sh
|
||||
|
||||
# Add time zone data
|
||||
RUN apk --no-cache add tzdata
|
||||
RUN apk --update --no-cache add tzdata tini
|
||||
COPY docker/entrypoint.sh /entrypoint.sh
|
||||
RUN chmod 0755 /entrypoint.sh && mkdir files
|
||||
|
||||
# Files permissions
|
||||
RUN mkdir /app/vikunja/files && \
|
||||
chown -R vikunja /app/vikunja/files
|
||||
VOLUME /app/vikunja/files
|
||||
|
||||
CMD ["/run.sh"]
|
||||
EXPOSE 3456
|
||||
COPY --from=builder /build/vikunja-* vikunja
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
#!/usr/bin/env sh
|
||||
set -e
|
||||
|
||||
if [ -n "$PUID" ] && [ "$PUID" -ne 0 ] && \
|
||||
[ -n "$PGID" ] && [ "$PGID" -ne 0 ] ; then
|
||||
echo "info: creating the new user vikunja with $PUID:$PGID"
|
||||
addgroup -g "$PGID" vikunja
|
||||
adduser -s /bin/sh -D -G vikunja -u "$PUID" vikunja -h /app/vikunja -H
|
||||
chown -R vikunja:vikunja ./
|
||||
su -pc /app/vikunja/vikunja - vikunja "$@"
|
||||
else
|
||||
echo "info: creation of non-root user is skipped"
|
||||
exec /app/vikunja/vikunja "$@"
|
||||
fi
|
||||
|
|
@ -47,10 +47,7 @@ which will run the docker image and expose port 80 on the host.
|
|||
|
||||
See [full docker example]({{< ref "full-docker-example.md">}}) for more varations of this config.
|
||||
|
||||
### Setting user and group id of the user running vikunja
|
||||
|
||||
You can set the user and group id of the user running vikunja with the `PUID` and `PGID` evironment variables.
|
||||
This follows the pattern used by [the linuxserver.io](https://docs.linuxserver.io/general/understanding-puid-and-pgid) docker images.
|
||||
The docker container runs as an unprivileged user and does not mount anything.
|
||||
|
||||
### API URL configuration in docker
|
||||
|
||||
|
|
2
go.mod
2
go.mod
|
@ -58,7 +58,7 @@ require (
|
|||
github.com/spf13/cobra v1.6.1
|
||||
github.com/spf13/viper v1.15.0
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/swaggo/swag v1.8.9
|
||||
github.com/swaggo/swag v1.8.10
|
||||
github.com/tkuchiki/go-timezone v0.2.2
|
||||
github.com/ulule/limiter/v3 v3.10.0
|
||||
github.com/vectordotdev/go-datemath v0.1.1-0.20211214182920-0a4ac8742b93
|
||||
|
|
2
go.sum
2
go.sum
|
@ -758,6 +758,8 @@ github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8
|
|||
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
||||
github.com/swaggo/swag v1.8.9 h1:kHtaBe/Ob9AZzAANfcn5c6RyCke9gG9QpH0jky0I/sA=
|
||||
github.com/swaggo/swag v1.8.9/go.mod h1:ezQVUUhly8dludpVk+/PuwJWvLLanB13ygV5Pr9enSk=
|
||||
github.com/swaggo/swag v1.8.10 h1:eExW4bFa52WOjqRzRD58bgWsWfdFJso50lpbeTcmTfo=
|
||||
github.com/swaggo/swag v1.8.10/go.mod h1:ezQVUUhly8dludpVk+/PuwJWvLLanB13ygV5Pr9enSk=
|
||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||
github.com/tkuchiki/go-timezone v0.2.2 h1:MdHR65KwgVTwWFQrota4SKzc4L5EfuH5SdZZGtk/P2Q=
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"code.vikunja.io/api/pkg/log"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"xorm.io/builder"
|
||||
"xorm.io/xorm"
|
||||
"xorm.io/xorm/names"
|
||||
)
|
||||
|
@ -102,3 +103,10 @@ func AssertMissing(t *testing.T, table string, values map[string]interface{}) {
|
|||
assert.NoError(t, err, fmt.Sprintf("Failed to assert entries don't exist in db, error was: %s", err))
|
||||
assert.False(t, exists, fmt.Sprintf("Entries %v exist in table %s", values, table))
|
||||
}
|
||||
|
||||
// AssertCount checks if a number of entries exists in the database
|
||||
func AssertCount(t *testing.T, table string, where builder.Cond, count int64) {
|
||||
dbCount, err := x.Table(table).Where(where).Count()
|
||||
assert.NoError(t, err, fmt.Sprintf("Failed to assert count in db, error was: %s", err))
|
||||
assert.Equal(t, count, dbCount, fmt.Sprintf("Found %d entries instead of expected %d in table %s", dbCount, count, table))
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"code.vikunja.io/api/pkg/user"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
func TestTask_Create(t *testing.T) {
|
||||
|
@ -367,6 +368,27 @@ func TestTask_Update(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
assert.Equal(t, int64(3), task.Index)
|
||||
})
|
||||
t.Run("the same date multiple times should be saved once", func(t *testing.T) {
|
||||
db.LoadAndAssertFixtures(t)
|
||||
s := db.NewSession()
|
||||
defer s.Close()
|
||||
|
||||
task := &Task{
|
||||
ID: 1,
|
||||
Title: "test",
|
||||
Reminders: []time.Time{
|
||||
time.Unix(1674745156, 0),
|
||||
time.Unix(1674745156, 223),
|
||||
},
|
||||
ListID: 1,
|
||||
}
|
||||
err := task.Update(s, u)
|
||||
assert.NoError(t, err)
|
||||
err = s.Commit()
|
||||
assert.NoError(t, err)
|
||||
|
||||
db.AssertCount(t, "task_reminders", builder.Eq{"task_id": 1}, 1)
|
||||
})
|
||||
}
|
||||
|
||||
func TestTask_Delete(t *testing.T) {
|
||||
|
|
|
@ -295,6 +295,11 @@ func GetListBackground(c echo.Context) error {
|
|||
_ = s.Rollback()
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
stat, err := bgFile.File.Stat()
|
||||
if err != nil {
|
||||
_ = s.Rollback()
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
||||
// Unsplash requires pingbacks as per their api usage guidelines.
|
||||
// To do this in a privacy-preserving manner, we do the ping from inside of Vikunja to not expose any user details.
|
||||
|
@ -306,6 +311,11 @@ func GetListBackground(c echo.Context) error {
|
|||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
||||
// Set Last-Modified header if we have the file stat, so clients can decide whether to use cached files
|
||||
if stat != nil {
|
||||
c.Response().Header().Set(echo.HeaderLastModified, stat.ModTime().UTC().Format(http.TimeFormat))
|
||||
}
|
||||
|
||||
// Serve the file
|
||||
return c.Stream(http.StatusOK, "image/jpg", bgFile.File)
|
||||
}
|
||||
|
|
|
@ -226,6 +226,9 @@ func insertFromStructure(s *xorm.Session, str []*models.NamespaceWithListsAndTas
|
|||
// If not, create one and save it for later
|
||||
var lb *models.Label
|
||||
var exists bool
|
||||
if label == nil {
|
||||
continue
|
||||
}
|
||||
lb, exists = labels[label.Title+label.HexColor]
|
||||
if !exists {
|
||||
err = label.Create(s, user)
|
||||
|
|
|
@ -35,6 +35,8 @@ import (
|
|||
"code.vikunja.io/api/pkg/utils"
|
||||
)
|
||||
|
||||
const paginationLimit = 200
|
||||
|
||||
// Migration is the todoist migration struct
|
||||
type Migration struct {
|
||||
Code string `json:"code"`
|
||||
|
@ -554,7 +556,7 @@ func (m *Migration) Migrate(u *user.User) (err error) {
|
|||
doneItems := make(map[string]*doneItem)
|
||||
|
||||
for {
|
||||
resp, err = migration.DoPostWithHeaders("https://api.todoist.com/sync/v9/completed/get_all?limit=200&offset="+strconv.Itoa(offset), form, bearerHeader)
|
||||
resp, err = migration.DoPostWithHeaders("https://api.todoist.com/sync/v9/completed/get_all?limit="+strconv.Itoa(paginationLimit)+"&offset="+strconv.Itoa(offset*paginationLimit), form, bearerHeader)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue