83 Commits

Author SHA1 Message Date
039bd77ec1 Add more specific settings for HTTPRoute (#203)
* Adding Helm chart

* Update maintainer

* Updating filesystem settings to prevent issues

* CREATE_CLIENTS is now true by default

* Add name override options

* Validation for postges

* Fix plain connection string in pod env

* Simplifying secret management

* Fix port quoting

* Init container to run sql file

* Fix port type

* Fix secret management

* Working now

* Fixing Postgres connection issue

* Upgrade postgres init container

* Auto add UUIDs when starting postgres

* feat: Use standard value names for adding HTTPReoute

* fix: Remove merge issues

* chore: bump version
2026-05-29 17:30:07 +00:00
7d772f4b5e Add GitHub Action to test the helm chart before merging (#205)
* Adding Helm chart

* Update maintainer

* Updating filesystem settings to prevent issues

* CREATE_CLIENTS is now true by default

* Add name override options

* Validation for postges

* Fix plain connection string in pod env

* Simplifying secret management

* Fix port quoting

* Init container to run sql file

* Fix port type

* Fix secret management

* Working now

* Fixing Postgres connection issue

* Upgrade postgres init container

* Auto add UUIDs when starting postgres

* Add Github action to publish new Helm charts on push

* Fixing url

* Removing duplicate files

* Adding documentation for helm chart

* Reorganizing

* Adding helm testing
2026-05-29 17:22:28 +00:00
865203fa93 Merge pull request #202 from GothenburgBitFactory/dependabot/cargo/openssl-0.10.80
Bump openssl from 0.10.79 to 0.10.80
2026-05-29 16:40:29 +00:00
0f422af080 Bump openssl from 0.10.79 to 0.10.80
Bumps [openssl](https://github.com/rust-openssl/rust-openssl) from 0.10.79 to 0.10.80.
- [Release notes](https://github.com/rust-openssl/rust-openssl/releases)
- [Commits](https://github.com/rust-openssl/rust-openssl/compare/openssl-v0.10.79...openssl-v0.10.80)

---
updated-dependencies:
- dependency-name: openssl
  dependency-version: 0.10.80
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-28 17:55:41 +00:00
2aab707178 Merge pull request #201 from GothenburgBitFactory/dependabot/github_actions/github-actions-45018e1108 2026-05-18 22:42:19 -06:00
7556092a84 Bump the github-actions group with 3 updates
Bumps the github-actions group with 3 updates: [actions/checkout](https://github.com/actions/checkout), [azure/setup-helm](https://github.com/azure/setup-helm) and [helm/chart-releaser-action](https://github.com/helm/chart-releaser-action).


Updates `actions/checkout` from 4 to 6
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v6)

Updates `azure/setup-helm` from 4 to 5
- [Release notes](https://github.com/azure/setup-helm/releases)
- [Changelog](https://github.com/Azure/setup-helm/blob/main/CHANGELOG.md)
- [Commits](https://github.com/azure/setup-helm/compare/v4...v5)

Updates `helm/chart-releaser-action` from 1.6.0 to 1.7.0
- [Release notes](https://github.com/helm/chart-releaser-action/releases)
- [Commits](https://github.com/helm/chart-releaser-action/compare/v1.6.0...v1.7.0)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: azure/setup-helm
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: helm/chart-releaser-action
  dependency-version: 1.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-17 23:52:57 +00:00
79118c0366 Forgot to fix the chart path (#200) 2026-05-12 11:44:49 -04:00
5165897200 Helm-chart GitHub action (#199) 2026-05-12 08:00:16 -04:00
d7d9de3bbe Auto add UUIDs when starting postgres 2026-05-11 21:11:11 -04:00
269efce4f1 Upgrade postgres init container 2026-05-11 21:11:11 -04:00
ef98290f37 Fixing Postgres connection issue 2026-05-11 21:11:11 -04:00
79d54cae5d Working now 2026-05-11 21:11:11 -04:00
2f84198600 Fix secret management 2026-05-11 21:11:11 -04:00
c857163d85 Fix port type 2026-05-11 21:11:11 -04:00
27c3f954c9 Init container to run sql file 2026-05-11 21:11:11 -04:00
a8f7281786 Fix port quoting 2026-05-11 21:11:11 -04:00
84c06475c6 Simplifying secret management 2026-05-11 21:11:11 -04:00
c58bb4800d Fix plain connection string in pod env 2026-05-11 21:11:11 -04:00
eee66c5475 Validation for postges 2026-05-11 21:11:11 -04:00
9bddb2f261 Add name override options 2026-05-11 21:11:11 -04:00
911c0cbc57 CREATE_CLIENTS is now true by default 2026-05-11 21:11:11 -04:00
ed3b5553fa Updating filesystem settings to prevent issues 2026-05-11 21:11:11 -04:00
583d7dbe63 Update maintainer 2026-05-11 21:11:11 -04:00
b98c87798c Adding Helm chart 2026-05-11 21:11:11 -04:00
dd1b87dad5 Bump the github-actions group with 2 updates
Bumps the github-actions group with 2 updates: [actions/add-to-project](https://github.com/actions/add-to-project) and [docker/build-push-action](https://github.com/docker/build-push-action).


Updates `actions/add-to-project` from 1.0.2 to 2.0.0
- [Release notes](https://github.com/actions/add-to-project/releases)
- [Commits](https://github.com/actions/add-to-project/compare/v1.0.2...v2.0.0)

Updates `docker/build-push-action` from 6 to 7
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/add-to-project
  dependency-version: 2.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: docker/build-push-action
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-11 20:53:32 -04:00
e1bebc7325 Bump openssl from 0.10.78 to 0.10.79
Bumps [openssl](https://github.com/rust-openssl/rust-openssl) from 0.10.78 to 0.10.79.
- [Release notes](https://github.com/rust-openssl/rust-openssl/releases)
- [Commits](https://github.com/rust-openssl/rust-openssl/compare/openssl-v0.10.78...openssl-v0.10.79)

---
updated-dependencies:
- dependency-name: openssl
  dependency-version: 0.10.79
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-06 23:31:42 -04:00
5356f2baaa Bump actix-http from 3.12.0 to 3.12.1
Bumps [actix-http](https://github.com/actix/actix-web) from 3.12.0 to 3.12.1.
- [Release notes](https://github.com/actix/actix-web/releases)
- [Changelog](https://github.com/actix/actix-web/blob/main/CHANGES.md)
- [Commits](https://github.com/actix/actix-web/compare/http-v3.12.0...http-v3.12.1)

---
updated-dependencies:
- dependency-name: actix-http
  dependency-version: 3.12.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-25 09:26:40 -04:00
389113ce92 Bump openssl from 0.10.73 to 0.10.78
Bumps [openssl](https://github.com/rust-openssl/rust-openssl) from 0.10.73 to 0.10.78.
- [Release notes](https://github.com/rust-openssl/rust-openssl/releases)
- [Commits](https://github.com/rust-openssl/rust-openssl/compare/openssl-v0.10.73...openssl-v0.10.78)

---
updated-dependencies:
- dependency-name: openssl
  dependency-version: 0.10.78
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-25 09:26:21 -04:00
25d8708630 Add an MSRV comment to Dockerfiles 2026-04-18 08:34:21 -04:00
6746e6ed3b Update Rust version
Signed-off-by: Evangelos Lamprou <vagos@lamprou.xyz>
2026-04-17 07:53:03 -04:00
bac5e50448 Fix docker build invocations (#188)
Signed-off-by: Evangelos Lamprou <vagos@lamprou.xyz>
2026-04-17 07:51:27 -04:00
da96579546 Bump rand from 0.9.1 to 0.9.4 (#186)
Bumps [rand](https://github.com/rust-random/rand) from 0.9.1 to 0.9.4.
- [Release notes](https://github.com/rust-random/rand/releases)
- [Changelog](https://github.com/rust-random/rand/blob/0.9.4/CHANGELOG.md)
- [Commits](https://github.com/rust-random/rand/compare/rand_core-0.9.1...0.9.4)

---
updated-dependencies:
- dependency-name: rand
  dependency-version: 0.9.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-14 20:12:08 -04:00
4fe70cf030 Bump tokio from 1.51.0 to 1.52.0 in the cargo group (#187)
Bumps the cargo group with 1 update: [tokio](https://github.com/tokio-rs/tokio).


Updates `tokio` from 1.51.0 to 1.52.0
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.51.0...tokio-1.52.0)

---
updated-dependencies:
- dependency-name: tokio
  dependency-version: 1.52.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: cargo
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-14 20:11:51 -04:00
24674bb0e0 Bump tempfile from 3.23.0 to 3.27.0 in the cargo group (#185)
Bumps the cargo group with 1 update: [tempfile](https://github.com/Stebalien/tempfile).


Updates `tempfile` from 3.23.0 to 3.27.0
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/compare/v3.23.0...v3.27.0)

---
updated-dependencies:
- dependency-name: tempfile
  dependency-version: 3.27.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: cargo
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-06 20:41:39 -04:00
8a2092b176 Bump the cargo group across 1 directory with 2 updates (#184)
Bumps the cargo group with 2 updates in the / directory: [uuid](https://github.com/uuid-rs/uuid) and [tokio](https://github.com/tokio-rs/tokio).


Updates `uuid` from 1.22.0 to 1.23.0
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/v1.22.0...v1.23.0)

Updates `tokio` from 1.50.0 to 1.51.0
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.50.0...tokio-1.51.0)

---
updated-dependencies:
- dependency-name: uuid
  dependency-version: 1.23.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: cargo
- dependency-name: tokio
  dependency-version: 1.51.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: cargo
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-04 14:49:23 -04:00
c475c01f51 group dependabot updates (#182) 2026-03-12 22:13:48 -04:00
7f07803b5b Bump clap from 4.5.41 to 4.5.60 (#181)
Bumps [clap](https://github.com/clap-rs/clap) from 4.5.41 to 4.5.60.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.41...clap_complete-v4.5.60)

---
updated-dependencies:
- dependency-name: clap
  dependency-version: 4.5.60
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-12 22:01:21 -04:00
409bdd4d2b Bump docker/setup-qemu-action from 3 to 4 (#176)
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 20:16:31 -04:00
3b68d5aa3a Bump docker/login-action from 3 to 4 (#177)
Bumps [docker/login-action](https://github.com/docker/login-action) from 3 to 4.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 20:16:22 -04:00
832be300ca Bump docker/metadata-action from 5 to 6 (#179)
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5 to 6.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/v5...v6)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 20:16:14 -04:00
6c30505fb3 Bump docker/setup-buildx-action from 3 to 4 (#180)
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 20:15:59 -04:00
591f38943f Bump tokio from 1.49.0 to 1.50.0 (#174)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.49.0 to 1.50.0.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.49.0...tokio-1.50.0)

---
updated-dependencies:
- dependency-name: tokio
  dependency-version: 1.50.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-08 14:41:11 -04:00
5320b850c4 Bump uuid from 1.21.0 to 1.22.0 (#175)
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.21.0 to 1.22.0.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/v1.21.0...v1.22.0)

---
updated-dependencies:
- dependency-name: uuid
  dependency-version: 1.22.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-07 10:09:06 -05:00
c5e78104a2 Bump actix-web from 4.12.0 to 4.13.0 (#173)
Bumps [actix-web](https://github.com/actix/actix-web) from 4.12.0 to 4.13.0.
- [Release notes](https://github.com/actix/actix-web/releases)
- [Changelog](https://github.com/actix/actix-web/blob/main/CHANGES.md)
- [Commits](https://github.com/actix/actix-web/compare/web-v4.12.0...web-v4.13.0)

---
updated-dependencies:
- dependency-name: actix-web
  dependency-version: 4.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-18 20:00:57 -05:00
875e39d474 Bump uuid from 1.20.0 to 1.21.0 (#172)
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.20.0 to 1.21.0.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/v1.20.0...v1.21.0)

---
updated-dependencies:
- dependency-name: uuid
  dependency-version: 1.21.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-16 22:21:57 -05:00
3c6a599613 Bump time from 0.3.41 to 0.3.47 (#170)
Bumps [time](https://github.com/time-rs/time) from 0.3.41 to 0.3.47.
- [Release notes](https://github.com/time-rs/time/releases)
- [Changelog](https://github.com/time-rs/time/blob/main/CHANGELOG.md)
- [Commits](https://github.com/time-rs/time/compare/v0.3.41...v0.3.47)

---
updated-dependencies:
- dependency-name: time
  dependency-version: 0.3.47
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-07 09:32:40 -05:00
a6a8b7c68d Update MSRV to support newer versions of time (#171) 2026-02-07 09:13:10 -05:00
5bc24d43e3 Bump uuid from 1.19.0 to 1.20.0 (#169)
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.19.0 to 1.20.0.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/v1.19.0...v1.20.0)

---
updated-dependencies:
- dependency-name: uuid
  dependency-version: 1.20.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-04 20:49:12 -05:00
aa5e97a9fd Bump bytes from 1.10.1 to 1.11.1 (#168)
Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.10.1 to 1.11.1.
- [Release notes](https://github.com/tokio-rs/bytes/releases)
- [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/bytes/compare/v1.10.1...v1.11.1)

---
updated-dependencies:
- dependency-name: bytes
  dependency-version: 1.11.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-04 20:47:39 -05:00
3282386849 Bump tokio from 1.48.0 to 1.49.0 (#165)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.48.0 to 1.49.0.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.48.0...tokio-1.49.0)

---
updated-dependencies:
- dependency-name: tokio
  dependency-version: 1.49.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-05 20:59:30 -05:00
a862f02682 Bump actions/cache from 4 to 5 (#164)
Bumps [actions/cache](https://github.com/actions/cache) from 4 to 5.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-15 21:25:57 -05:00
2e69bea5ea Bump uuid from 1.18.0 to 1.19.0 (#163)
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.18.0 to 1.19.0.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/v1.18.0...v1.19.0)

---
updated-dependencies:
- dependency-name: uuid
  dependency-version: 1.19.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-01 23:03:54 -05:00
c60e95bbf0 Bump actions/checkout from 5 to 6 (#162)
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-27 22:41:56 -05:00
9cf07e9d80 Update actix-* to latest (#161) 2025-11-17 21:38:55 -05:00
c3470f4756 Add all new issues to the project (#159) 2025-11-13 19:31:39 -05:00
789106b517 Refactor Docker build commands in README (#157)
Updated Docker build commands for SQLite and Postgres to include Dockerfile specifications.

Fixes #156.
2025-11-01 15:30:52 -04:00
72aeebdda7 Bump rusqlite from 0.32.1 to 0.37.0 (#158)
Bumps [rusqlite](https://github.com/rusqlite/rusqlite) from 0.32.1 to 0.37.0.
- [Release notes](https://github.com/rusqlite/rusqlite/releases)
- [Changelog](https://github.com/rusqlite/rusqlite/blob/master/Changelog.md)
- [Commits](https://github.com/rusqlite/rusqlite/compare/v0.32.1...v0.37.0)

---
updated-dependencies:
- dependency-name: rusqlite
  dependency-version: 0.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-16 19:33:51 -04:00
eed6421a4e Bump tokio from 1.47.0 to 1.48.0 (#155)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.47.0 to 1.48.0.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.47.0...tokio-1.48.0)

---
updated-dependencies:
- dependency-name: tokio
  dependency-version: 1.48.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-14 20:33:46 -04:00
5d013073cb Bump to -pre version 2025-10-11 19:02:31 +00:00
67524a0a91 Simplify cargo publish steps in RELEASING.md
Updated release instructions to simplify publishing process.
2025-10-11 14:58:26 -04:00
d206729d5e v0.7.1 2025-10-11 18:57:23 +00:00
bf19b76577 Bump actix-rt from 2.10.0 to 2.11.0 (#151)
Bumps [actix-rt](https://github.com/actix/actix-net) from 2.10.0 to 2.11.0.
- [Release notes](https://github.com/actix/actix-net/releases)
- [Commits](https://github.com/actix/actix-net/compare/rt-v2.10.0...rt-v2.11.0)

---
updated-dependencies:
- dependency-name: actix-rt
  dependency-version: 2.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-10 21:21:10 -04:00
505dd3f442 Bump tempfile from 3.22.0 to 3.23.0 (#153)
Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.22.0 to 3.23.0.
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/compare/v3.22.0...v3.23.0)

---
updated-dependencies:
- dependency-name: tempfile
  dependency-version: 3.23.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-23 22:09:46 -04:00
e10f3e6cfb Bump tempfile from 3.21.0 to 3.22.0 (#152)
Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.21.0 to 3.22.0.
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/compare/v3.21.0...v3.22.0)

---
updated-dependencies:
- dependency-name: tempfile
  dependency-version: 3.22.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-10 19:04:12 -04:00
213be852b8 Fix add_version calls when no history exists on the server (#149)
This fixes a bug in 25911b44a6 where the
check in the storage implementation was too strict (not allowing
`clients.latest_version_id == Uuid::nil()`), causing spurious failures.

Well, two bugs, one in each storage implementation.
2025-08-20 15:21:04 -04:00
b57dd24d9e Bump tempfile from 3.20.0 to 3.21.0 (#150)
Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.20.0 to 3.21.0.
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/commits)

---
updated-dependencies:
- dependency-name: tempfile
  dependency-version: 3.21.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-20 08:45:41 -04:00
a9cf67c8e2 Document Cargo features in the binaries page (#148) 2025-08-18 08:29:32 -04:00
daf6855f14 Bump slab from 0.4.10 to 0.4.11 (#147)
Bumps [slab](https://github.com/tokio-rs/slab) from 0.4.10 to 0.4.11.
- [Release notes](https://github.com/tokio-rs/slab/releases)
- [Changelog](https://github.com/tokio-rs/slab/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/slab/compare/v0.4.10...v0.4.11)

---
updated-dependencies:
- dependency-name: slab
  dependency-version: 0.4.11
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 22:09:38 -04:00
dbc9a6909b Bump actions/checkout from 4 to 5 (#145)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 19:55:19 -04:00
1ad9e344c7 Bump uuid from 1.17.0 to 1.18.0 (#146)
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.17.0 to 1.18.0.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/v1.17.0...v1.18.0)

---
updated-dependencies:
- dependency-name: uuid
  dependency-version: 1.18.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 19:55:00 -04:00
3820a8deea Document the different sslmodes recognized by the postgres crate (#144)
LibPQ will happily accept invalid certificates or hostnames, while the
Rust client will not. This can cause some confusion, so draw attention
to it here.
2025-08-04 07:24:59 -04:00
2de70ac336 Capture and log errors from bb8 (#143) 2025-08-03 11:13:58 -04:00
c2b4c94fb5 Merge remote-tracking branch 'origin/main' 2025-08-02 21:01:41 -04:00
0a317cd86d Only publish docs on tags (#136) 2025-08-01 17:48:34 -04:00
1b80398365 Merge post-0.7.0-release updates into main 2025-07-30 22:41:25 -04:00
5a2bd4cde7 Use git context for building docker images 2025-07-30 21:50:30 -04:00
e5b35210af include dockerfiles in context 2025-07-30 21:38:58 -04:00
3bbfcb9f88 Fix Dockerfile reference 2025-07-30 21:35:21 -04:00
8752531e2c Use correct option to docker/build-push-action for Dockerfiles 2025-07-30 21:33:46 -04:00
a94be2649e Use correct option to docker/build-push-action for Dockerfiles 2025-07-30 21:32:27 -04:00
624efa8b0d stop excluding the postgres crate 2025-07-30 21:23:53 -04:00
ae9adf1572 Bump to -pre version 2025-07-30 21:23:03 -04:00
547621950f v0.7.0 2025-07-30 21:20:25 -04:00
42 changed files with 1573 additions and 315 deletions

View File

@ -6,3 +6,4 @@
!sqlite/
!postgres/
!entrypoint-*
!Dockerfile*

View File

@ -5,6 +5,9 @@ updates:
directory: "/"
schedule:
interval: "weekly"
groups:
github-actions:
patterns: ["*"]
# Enable updates for Rust packages
- package-ecosystem: "cargo"
directory: "/" # Location of package manifests
@ -16,3 +19,8 @@ updates:
# behind
- dependency-name: "*"
update-types: ["version-update:semver-patch"]
groups:
cargo:
patterns: ["*"]
# leave major changes in their own PRs
update-types: ["minor", "patch"]

18
.github/workflows/add-to-project.yml vendored Normal file
View File

@ -0,0 +1,18 @@
# This adds all new issues to the Taskwarrior project, for better tracking.
# It uses a PAT that belongs to @taskwarrior.
name: Add issues to Taskwarrior Project
on:
issues:
types:
- opened
jobs:
add-to-project:
name: Add issue to project
runs-on: ubuntu-latest
steps:
- uses: actions/add-to-project@v2.0.0
with:
project-url: https://github.com/orgs/GothenburgBitFactory/projects/4
github-token: ${{ secrets.ADD_TO_PROJECT_PAT }}

View File

@ -13,16 +13,16 @@ jobs:
name: "Check & Clippy"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Cache cargo registry
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo build
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: target
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
@ -48,10 +48,10 @@ jobs:
name: "Rustdoc"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Cache cargo registry
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
@ -96,7 +96,7 @@ jobs:
runs-on: ubuntu-latest
name: "Formatting"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- uses: actions-rs/toolchain@v1
with:
@ -114,19 +114,18 @@ jobs:
runs-on: ubuntu-latest
name: "Cargo Semver Checks"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- uses: obi1kenobi/cargo-semver-checks-action@v2
with:
# exclude the binary package from semver checks, since it is not published as a crate.
# exclude postgres temporarily until it is released
exclude: taskchampion-sync-server,taskchampion-sync-server-storage-postgres
exclude: taskchampion-sync-server
mdbook:
runs-on: ubuntu-latest
name: "mdBook Documentation"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Setup mdBook
uses: peaceiris/actions-mdbook@v2

View File

@ -10,18 +10,18 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
uses: docker/setup-qemu-action@v4
- name: Login to ghcr.io
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Docker meta
id: meta-sqlite
uses: docker/metadata-action@v5
uses: docker/metadata-action@v6
with:
images: |
ghcr.io/gothenburgbitfactory/taskchampion-sync-server
@ -31,10 +31,9 @@ jobs:
type=semver,pattern={{major}}.{{minor}}
type=match,pattern=\d.\d.\d,value=latest
- name: Build and push
uses: docker/build-push-action@v6
uses: docker/build-push-action@v7
with:
context: .
path: "{context}/Dockerfile-sqlite"
file: "./Dockerfile-sqlite"
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta-sqlite.outputs.tags }}
@ -43,16 +42,16 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4
- name: Login to ghcr.io
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Docker meta
id: meta-postgres
uses: docker/metadata-action@v5
uses: docker/metadata-action@v6
with:
images: |
ghcr.io/gothenburgbitfactory/taskchampion-sync-server-postgres
@ -62,10 +61,9 @@ jobs:
type=semver,pattern={{major}}.{{minor}}
type=match,pattern=\d.\d.\d,value=latest
- name: Build and push
uses: docker/build-push-action@v6
uses: docker/build-push-action@v7
with:
context: .
path: "{context}/Dockerfile-postgres"
file: "./Dockerfile-postgres"
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta-postgres.outputs.tags }}

171
.github/workflows/helm-test.yml vendored Normal file
View File

@ -0,0 +1,171 @@
name: Helm Chart Tests
on:
push:
branches: [main]
paths:
- 'helm/**'
pull_request:
paths:
- 'helm/**'
jobs:
helm-test:
runs-on: ubuntu-latest
name: "Helm Lint & Template"
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Helm
uses: azure/setup-helm@v5
with:
version: latest
- name: Helm lint (default values — expects failure, no backend enabled)
run: |
helm lint helm/taskchampion-sync-server \
--strict 2>&1 || true
- name: Template default values — must fail validation
run: |
if helm template test-release helm/taskchampion-sync-server 2>/dev/null; then
echo "❌ Expected chart to fail validation (no backend enabled) but it succeeded"
exit 1
fi
echo "✓ Correctly rejects chart with no backend enabled"
- name: Template with SQLite values
run: |
helm template test-release helm/taskchampion-sync-server \
-f helm/taskchampion-sync-server/examples/sqlite-values.yaml \
--debug > /tmp/helm-sqlite.yaml
echo "=== Generated resources (SQLite) ==="
grep -E '^# Source:' /tmp/helm-sqlite.yaml
# Verify key resources exist
grep -q 'kind: Deployment' /tmp/helm-sqlite.yaml
grep -q 'kind: Service' /tmp/helm-sqlite.yaml
grep -q 'kind: Ingress' /tmp/helm-sqlite.yaml
grep -q 'kind: ServiceAccount' /tmp/helm-sqlite.yaml
# Verify SQLite-specific rendering
grep -q 'emptyDir' /tmp/helm-sqlite.yaml
grep -q 'DATA_DIR' /tmp/helm-sqlite.yaml
# Verify PostgreSQL-specific rendering is absent
if grep -q 'initContainers' /tmp/helm-sqlite.yaml; then
echo "❌ initContainers should not appear in SQLite mode"
exit 1
fi
if grep -q 'CONNECTION' /tmp/helm-sqlite.yaml; then
echo "❌ CONNECTION env var should not appear in SQLite mode"
exit 1
fi
# Verify correct image tag (no -postgres suffix)
grep -q 'image:.*taskchampion-sync-server:0.7.0' /tmp/helm-sqlite.yaml
echo "✓ SQLite template generated successfully"
- name: Template with PostgreSQL values
run: |
helm template test-release helm/taskchampion-sync-server \
-f helm/taskchampion-sync-server/examples/postgres-values.yaml \
--debug > /tmp/helm-postgres.yaml
echo "=== Generated resources (PostgreSQL) ==="
grep -E '^# Source:' /tmp/helm-postgres.yaml
# Verify key resources exist
grep -q 'kind: Deployment' /tmp/helm-postgres.yaml
grep -q 'kind: Service' /tmp/helm-postgres.yaml
grep -q 'kind: Secret' /tmp/helm-postgres.yaml
grep -q 'kind: ServiceAccount' /tmp/helm-postgres.yaml
# Verify PostgreSQL-specific rendering
grep -q 'kind: HTTPRoute' /tmp/helm-postgres.yaml
grep -q 'initContainers' /tmp/helm-postgres.yaml
grep -q 'CONNECTION' /tmp/helm-postgres.yaml
grep -q 'replicas: 3' /tmp/helm-postgres.yaml
# Verify correct image tag (with -postgres suffix)
grep -q 'image:.*taskchampion-sync-server-postgres:0.7.0' /tmp/helm-postgres.yaml
# Verify SQLite-specific rendering is absent
if grep -q 'DATA_DIR' /tmp/helm-postgres.yaml; then
echo "❌ DATA_DIR env var should not appear in PostgreSQL mode"
exit 1
fi
echo "✓ PostgreSQL template generated successfully"
- name: Template with both backends enabled — must fail validation
run: |
if helm template test-release helm/taskchampion-sync-server \
--set sqlite.enabled=true \
--set postgres.enabled=true 2>/dev/null; then
echo "❌ Expected chart to fail validation (both backends enabled) but it succeeded"
exit 1
fi
echo "✓ Correctly rejects chart with both backends enabled"
- name: Template with custom overrides
run: |
helm template test-release helm/taskchampion-sync-server \
--set sqlite.enabled=true \
--set postgres.enabled=false \
--set nameOverride=custom-name \
--set image.tag=latest \
--debug > /tmp/helm-custom.yaml
# Verify custom name override
grep -q 'custom-name' /tmp/helm-custom.yaml
grep -q 'custom-name-pvc' /tmp/helm-custom.yaml
# Verify custom image tag
grep -q 'image:.*taskchampion-sync-server:latest' /tmp/helm-custom.yaml
echo "✓ Custom overrides template generated successfully"
- name: Helm install dry-run (SQLite)
run: |
helm install test-release helm/taskchampion-sync-server \
-f helm/taskchampion-sync-server/examples/sqlite-values.yaml \
--dry-run 2>&1 | head -5
echo "✓ Helm install dry-run (SQLite) succeeded"
helm-kubeconform:
runs-on: ubuntu-latest
name: "Kubeconform Validation"
needs: helm-test
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Helm
uses: azure/setup-helm@v5
with:
version: latest
- name: Download kubeconform
run: |
wget -q -O /tmp/kubeconform.tar.gz \
https://github.com/yannh/kubeconform/releases/download/v0.6.7/kubeconform-linux-amd64.tar.gz
tar -xzf /tmp/kubeconform.tar.gz -C /usr/local/bin/ kubeconform
kubeconform -v
- name: Validate SQLite output against Kubernetes schemas
run: |
helm template test-release helm/taskchampion-sync-server \
-f helm/taskchampion-sync-server/examples/sqlite-values.yaml > /tmp/helm-sqlite.yaml
kubeconform -strict /tmp/helm-sqlite.yaml
echo "✓ SQLite resources are valid Kubernetes manifests"
- name: Validate PostgreSQL output against Kubernetes schemas
run: |
helm template test-release helm/taskchampion-sync-server \
-f helm/taskchampion-sync-server/examples/postgres-values.yaml > /tmp/helm-postgres.yaml
# Skip kubeconform on HTTPRoute since Gateway API CRDs aren't bundled
kubeconform -strict -ignore-missing-schemas /tmp/helm-postgres.yaml
echo "✓ PostgreSQL resources are valid Kubernetes manifests"

View File

@ -2,8 +2,8 @@ name: docs
on:
push:
branches:
- main
tags:
- '*'
permissions:
contents: write
@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Setup mdBook
uses: peaceiris/actions-mdbook@v2
@ -28,3 +28,4 @@ jobs:
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs/book
keep_files: true

37
.github/workflows/publish-helm.yml vendored Normal file
View File

@ -0,0 +1,37 @@
name: Publish Helm Charts
on:
push:
branches:
- main
paths:
- 'helm/**'
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Configure Git
run: |
git config user.name "$GITHUB_ACTOR"
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
- name: Install Helm
uses: azure/setup-helm@v5
- name: Run chart-releaser
uses: helm/chart-releaser-action@v1.7.0
env:
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
with:
charts_dir: helm
charts_repo_url: https://gothenburgbitfactory.org/taskchampion-sync-server/helm-chart
pages_index_path: helm-charts

View File

@ -15,7 +15,7 @@ jobs:
- "17"
rust:
# MSRV
- "1.85.0"
- "1.88.0"
- "stable"
runs-on: ubuntu-latest
@ -39,16 +39,16 @@ jobs:
--health-retries 5
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Cache cargo registry
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-${{ matrix.rust }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo build
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: target
key: ${{ runner.os }}-${{ matrix.rust }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}

View File

@ -14,7 +14,7 @@ jobs:
permissions: write-all
name: "Audit Rust Dependencies"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- uses: rustsec/audit-check@v2.0.0
with:
token: ${{ secrets.GITHUB_TOKEN }}

623
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -6,30 +6,30 @@ members = [
"sqlite",
"postgres",
]
rust-version = "1.85.0" # MSRV
rust-version = "1.88.0" # MSRV
[workspace.dependencies]
async-trait = "0.1.88"
uuid = { version = "^1.17.0", features = ["serde", "v4"] }
actix-web = "^4.11.0"
uuid = { version = "^1.23.0", features = ["serde", "v4"] }
actix-web = "^4.13.0"
anyhow = "1.0"
thiserror = "2.0"
futures = "^0.3.25"
serde_json = "^1.0"
serde = { version = "^1.0.147", features = ["derive"] }
clap = { version = "^4.5.6", features = ["string", "env"] }
clap = { version = "^4.5.60", features = ["string", "env"] }
log = "^0.4.17"
env_logger = "^0.11.7"
rusqlite = { version = "0.32", features = ["bundled"] }
rusqlite = { version = "0.37", features = ["bundled"] }
chrono = { version = "^0.4.38", features = ["serde"] }
actix-rt = "2"
tempfile = "3"
pretty_assertions = "1"
temp-env = "0.3"
tokio = { version = "*", features = ["rt", "macros"] }
tokio = { version = "1.52", features = ["rt", "macros"] }
tokio-postgres = { version = "0.7.13", features = ["with-uuid-1"] }
bb8 = "0.9.0"
bb8-postgres = { version = "0.9.0", features = ["with-uuid-1"] }
openssl = { version = "0.10.73", default-features = false, features = ["vendored"] }
openssl = { version = "0.10.80", default-features = false, features = ["vendored"] }
native-tls = { version = "0.2.14", default-features = false, features = ["vendored"] }
postgres-native-tls = "0.5.1"

View File

@ -1,6 +1,7 @@
# Versions must be major.minor
# Default versions are as below
ARG RUST_VERSION=1.85
# RUST_VERSION should match the MSRV in Cargo.toml.
ARG RUST_VERSION=1.88
ARG ALPINE_VERSION=3.20
FROM docker.io/rust:${RUST_VERSION}-alpine${ALPINE_VERSION} AS builder

View File

@ -1,6 +1,7 @@
# Versions must be major.minor
# Default versions are as below
ARG RUST_VERSION=1.85
# RUST_VERSION should match the MSRV in Cargo.toml.
ARG RUST_VERSION=1.88
ARG ALPINE_VERSION=3.20
FROM docker.io/rust:${RUST_VERSION}-alpine${ALPINE_VERSION} AS builder

View File

@ -74,20 +74,17 @@ To build the images, execute the following commands.
SQLite:
```sh
source .env
docker build \
--build-arg RUST_VERSION=${RUST_VERSION} \
--build-arg ALPINE_VERSION=${ALPINE_VERSION} \
-t taskchampion-sync-server docker/sqlite
-t taskchampion-sync-server \
-f Dockerfile-sqlite .
```
Postgres:
```sh
source .env
docker build \
--build-arg RUST_VERSION=${RUST_VERSION} \
--build-arg ALPINE_VERSION=${ALPINE_VERSION} \
-t taskchampion-sync-server-postgres docker/postgres
-t taskchampion-sync-server-postgres \
-f Dockerfile-postgres .
```
Now to run it, simply exec.

View File

@ -4,7 +4,7 @@
1. Run `cargo test`
1. Run `cargo clean && cargo clippy`
1. Remove the `-pre` from `version` in all `*/Cargo.toml`, and from the `version = ..` in any references between packages.
1. Update the link to `docker-compose.yml` in `README.md` to refer to the new version.
1. Update the link to `docker-compose.yml` in `docs/src/usage/docker-compose.md` to refer to the new version.
1. Update the docker image in `docker-compose.yml` to refer to the new version.
1. Run `cargo semver-checks` (https://crates.io/crates/cargo-semver-checks)
1. Run `cargo build --release`
@ -12,66 +12,9 @@
1. Run `git tag vX.Y.Z`
1. Run `git push upstream`
1. Run `git push upstream --tag vX.Y.Z`
1. Run `cargo publish -p taskchampion-sync-server-core`
1. Run `cargo publish -p taskchampion-sync-server-storage-sqlite` (and add any other new published packages here)
1. Run `cargo publish` to publish all packages in the workspace
1. Bump the patch version in `*/Cargo.toml` and add the `-pre` suffix. This allows `cargo-semver-checks` to check for changes not accounted for in the version delta.
1. Run `cargo build --release` again to update `Cargo.lock`
1. Commit that change with comment "Bump to -pre version".
1. Run `git push upstream`
1. Navigate to the tag in the GitHub releases UI and create a release with general comments about the changes in the release
---
For the next release,
- remove postgres from the exclusion list in `.github/workflows/checks.yml` after the release
- include the folowing in the release notes:
Running the Docker image for this server without specifying DATA_DIR
defaulted to storing the server data in
`/var/lib/taskchampion-sync-server`. However, the Dockerfile only
specifies that the subdirectory `/var/lib/taskchampion-sync-server/data`
is a VOLUME. This change fixes the default to match the VOLUME, putting
the server data on an ephemeral volume or, if a `--volume
$NAME:/var/lib/taskchampion-sync-server/data` argument is provided to
`docker run`, in a named volume.
Before this commit, with default settings the server data is stored in
the container's ephemeral writeable layer. When the container is killed,
the data is lost. This issue does not affect deployments with `docker
compose`, as the compose configuration specifies a correct `DATA_DIR`.
You can determine if your deployment is affected as follows. First,
determine the ID of the running server container, `$CONTAINER`. Examine
the volumes for that container:
```shell
$ docker container inspect $CONTAINER | jq '.[0].Config.Volumes'
{
"/var/lib/task-champion-sync-server/data": {}
}
```
Next, find the server data, in a `.sqlite3` file:
```shell
$ docker exec $CONTAINER find /var/lib/taskchampion-sync-server
/var/lib/taskchampion-sync-server
/var/lib/taskchampion-sync-server/data
/var/lib/taskchampion-sync-server/taskchampion-sync-server.sqlite3
```
If the data is not in a directory mounted as a volume, then it is
ephemeral. To copy the data out of the container:
```shell
docker cp $CONTAINER:/var/lib/taskchampion-sync-server/taskchampion-sync-server.sqlite3 /tmp
```
You may then upgrade the image and use `docker cp` to copy the data back
to the correct location, `/var/lib/taskchampion-sync-server/data`.
Note that, as long as all replicas are fully synced, the TaskChampion
sync protocol is resilient to loss of server data, so even if the server
data has been lost, `task sync` may continue to work.

View File

@ -1,6 +1,6 @@
[package]
name = "taskchampion-sync-server-core"
version = "0.7.0-pre"
version = "0.7.2-pre"
authors = ["Dustin J. Mitchell <dustin@mozilla.com>"]
edition = "2021"
description = "Core of sync protocol for TaskChampion"

View File

@ -43,7 +43,7 @@ services:
condition: service_completed_successfully
tss:
image: ghcr.io/gothenburgbitfactory/taskchampion-sync-server:0.6.1
image: ghcr.io/gothenburgbitfactory/taskchampion-sync-server:0.7.1
restart: unless-stopped
environment:
- "RUST_LOG=info"

View File

@ -2,9 +2,10 @@
- [Introduction](./introduction.md)
- [Usage](./usage.md)
- [Docker Compose](./usage/docker-compose.md)
- [Docker Images](./usage/docker-images.md)
- [Binaries](./usage/binaries.md)
- [Docker Images](./usage/docker-images.md)
- [Docker Compose](./usage/docker-compose.md)
- [Helm](./usage/helm.md)
- [Integration](./integration.md)
- [Pre-built Images](./integration/pre-built.md)
- [Rust Crates](./integration/crates.md)

View File

@ -10,16 +10,38 @@ One binary is provided for each storage backend:
- `taskchampion-sync-server` (SQLite)
- `taskchampion-sync-server-postgres` (Postgres)
### Building the Binary
This is a standard Rust project, and can be built with `cargo build --release`.
By default, only the SQLite binary is built. To also build the Postgres binary,
use
```none
cargo build --release --features postgres
```
To disable building the SQLite binary and build only the Postgres binary, use
```none
cargo build --release --no-default-features --features postgres
```
### Running the Binary
The server is configured with command-line options or environment variables.
See the `--help` output for full details.
For the SQLite binary, the `--data-dir` option or `DATA_DIR` environment
variable specifies where the server should store its data. For the Postgres
binary, the `--connection` option or `CONNECTION` environment variable
specifies the connection information, in the form of a [LibPQ-style connection
variable specifies where the server should store its data.
For the Postgres binary, the `--connection` option or `CONNECTION` environment
variable specifies the connection information, in the form of a [LibPQ-style
connection
URI](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING-URIS).
Note that unlike LibPQ, the Rust client only supports `sslmode` values
`disable`, `prefer`, and `require`, and will always validate CA hostnames and
certificates when using TLS.
The remaining options are common to all binaries.
The `--listen` option specifies the interface and port the server listens on.

View File

@ -1,7 +1,7 @@
# Docker Compose
The
[`docker-compose.yml`](https://raw.githubusercontent.com/GothenburgBitFactory/taskchampion-sync-server/refs/tags/v0.6.1/docker-compose.yml)
[`docker-compose.yml`](https://raw.githubusercontent.com/GothenburgBitFactory/taskchampion-sync-server/refs/tags/v0.7.1/docker-compose.yml)
file in this repository is sufficient to run taskchampion-sync-server,
including setting up TLS certificates using Lets Encrypt, thanks to
[Caddy](https://caddyserver.com/). This setup uses the SQLite backend, which is

60
docs/src/usage/helm.md Normal file
View File

@ -0,0 +1,60 @@
# Helm
A Helm chart is available for deploying taskchampion-sync-server on Kubernetes.
## Adding the Repository
```sh
helm repo add taskchampion https://gothenburgbitfactory.org/taskchampion-sync-server/helm-chart
helm repo update
```
## Installing the Chart
The chart requires exactly one storage backend to be enabled. To install with
the SQLite backend:
```sh
helm install taskchampion-sync-server taskchampion/taskchampion-sync-server \
--set sqlite.enabled=true
```
To install with the Postgres backend, provide the connection details:
```sh
helm install taskchampion-sync-server taskchampion/taskchampion-sync-server \
--set postgres.enabled=true \
--set postgres.host=my-postgres \
--set postgres.database=taskchampion \
--set postgres.username=myuser \
--set postgres.password=mypassword
```
Alternatively, pass an existing Secret name via `postgres.existingSecret`. The
secret must contain a `connection` key holding a [LibPQ-style connection
URI](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING-URIS).
## Configuration
The chart does not implement TLS. The expectation is that a Kubernetes ingress
or gateway will terminate TLS and proxy HTTP traffic to the server container.
Enable one of the built-in options or configure your own:
```sh
# NGINX ingress
--set ingress.enabled=true --set ingress.hosts[0]=taskchampion.example.com
# Gateway API HTTPRoute
--set httpRoute.enabled=true \
--set httpRoute.gateway=my-gateway \
--set httpRoute.host=taskchampion.example.com
```
To restrict which client IDs the server accepts, create a Secret containing a
newline-separated list of UUIDs and reference it:
```sh
--set clientIdSecret=my-client-ids-secret
```
See the chart's `values.yaml` for the full set of configuration options.

View File

@ -0,0 +1,5 @@
# Patterns to ignore when building the Helm chart
.git
.gitignore
*.md
examples/

View File

@ -0,0 +1,17 @@
apiVersion: v2
name: taskchampion-sync-server
description: A Helm chart for deploying TaskChampion Sync Server on Kubernetes
type: application
version: 0.1.1
appVersion: "0.7.0"
keywords:
- taskchampion
- taskwarrior
- sync
- task-management
home: https://github.com/GothenburgBitFactory/taskchampion-sync-server
sources:
- https://github.com/GothenburgBitFactory/taskchampion-sync-server
maintainers:
- name: Jansen Fuller
email: jansendfuller@mailfence.com

View File

@ -0,0 +1,60 @@
# TaskChampion Sync Server Helm Chart
Deploy the [TaskChampion Sync Server](https://github.com/GothenburgBitFactory/taskchampion-sync-server) on Kubernetes.
## Prerequisites
- Kubernetes 1.23+
- Helm 3+
## Storage Backends
Exactly one storage backend must be enabled. The chart will fail validation if both or neither are enabled.
### SQLite
```console
helm install my-release ./helm/taskchampion-sync-server -f helm/taskchampion-sync-server/examples/sqlite-values.yaml
```
### PostgreSQL
```console
helm install my-release ./helm/taskchampion-sync-server -f helm/taskchampion-sync-server/examples/postgres-values.yaml
```
## Secrets
The chart expects pre-created secrets referenced by name:
### Client ID Secret
```yaml
apiVersion: v1
kind: Secret
metadata:
name: my-client-ids
type: Opaque
data:
client-ids: <base64-encoded comma-separated UUIDs>
```
Reference it via `clientIdSecret: "my-client-ids"`.
### PostgreSQL Secret
For PostgreSQL, the chart can automatically create a secret with the connection string, or use an existing secret.
**Automatic Secret Creation**:
- When `postgres.existingSecret` is empty (default), the chart automatically creates a secret
- Secret is named using Helm naming convention: `release-name-taskchampion-sync-server`
- Secret contains only a `connection` key with the built connection string
**Existing Secret Usage**:
- When `postgres.existingSecret` is provided, the chart uses that secret
- The secret **must** contain a `connection` key with the PostgreSQL connection string
- If the secret doesn't have a `connection` key, the deployment will fail with a clear error
## Configuration
See [values.yaml](values.yaml) for all configurable options.

View File

@ -0,0 +1,30 @@
sqlite:
enabled: false
postgres:
enabled: true
database: taskchampion
host: postgres-primary
username: taskchampion-user
clientIdSecret: "taskchampion-client-ids"
env:
RUST_LOG: debug
LISTEN: "0.0.0.0:8080"
CREATE_CLIENTS: "false"
replicas:
enabled: true
count: 3
image:
pullSecrets:
- my-registry-secret
httpRoute:
enabled: true
gateway: "my-gateway"
host: "taskchampion.example.com"
path: "/"
port: 8080

View File

@ -0,0 +1,22 @@
sqlite:
enabled: true
existingPV: ""
emptyDir:
sizeLimit: 1Gi
persistence:
enabled: false
postgres:
enabled: false
clientIdSecret: "taskchampion-client-ids"
env:
RUST_LOG: info
LISTEN: "0.0.0.0:8080"
CREATE_CLIENTS: "false"
ingress:
enabled: true
hosts:
- taskchampion.example.com

View File

@ -0,0 +1,102 @@
{{- /*
taskchampion-sync-server helpers
*/ -}}
{{- define "taskchampion-sync-server.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- define "taskchampion-sync-server.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{- define "taskchampion-sync-server.labels" -}}
helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
app.kubernetes.io/name: {{ include "taskchampion-sync-server.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{- define "taskchampion-sync-server.selectorLabels" -}}
app.kubernetes.io/name: {{ include "taskchampion-sync-server.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{- define "taskchampion-sync-server.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "taskchampion-sync-server.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
{{- define "taskchampion-sync-server.postgres-connection" -}}
{{- $host := .Values.postgres.host -}}
{{- $port := .Values.postgres.port | toString -}}
{{- $username := .Values.postgres.username -}}
{{- $password := .Values.postgres.password -}}
{{- $database := .Values.postgres.database -}}
{{- /* Override individual fields from existingSecret where present */ -}}
{{- if .Values.postgres.existingSecret -}}
{{- $secret := lookup "v1" "Secret" .Release.Namespace .Values.postgres.existingSecret -}}
{{- if $secret -}}
{{- if index $secret.data "host" -}}
{{- $host = index $secret.data "host" | b64dec -}}
{{- end -}}
{{- if index $secret.data "port" -}}
{{- $port = index $secret.data "port" | b64dec -}}
{{- end -}}
{{- if index $secret.data "username" -}}
{{- $username = index $secret.data "username" | b64dec -}}
{{- end -}}
{{- if index $secret.data "password" -}}
{{- $password = index $secret.data "password" | b64dec -}}
{{- end -}}
{{- if index $secret.data "database" -}}
{{- $database = index $secret.data "database" | b64dec -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- /* Build URI */ -}}
{{- $uri := "postgresql://" -}}
{{- if ne $username "" -}}
{{- $uri = printf "%s%s" $uri $username -}}
{{- if ne $password "" -}}
{{- $uri = printf "%s:%s" $uri $password -}}
{{- end -}}
{{- $uri = printf "%s@" $uri -}}
{{- end -}}
{{- $uri = printf "%s%s" $uri $host -}}
{{- if ne $port "5432" -}}
{{- $uri = printf "%s:%s" $uri $port -}}
{{- end -}}
{{- $uri = printf "%s/%s" $uri $database -}}
{{- if .Values.postgres.sslMode -}}
{{- $uri = printf "%s?sslmode=%s" $uri .Values.postgres.sslMode -}}
{{- end -}}
{{- $uri -}}
{{- end -}}
{{- define "taskchampion-sync-server.schema-url" -}}
{{- if .Values.postgres.initContainer.schemaUrl -}}
{{- .Values.postgres.initContainer.schemaUrl -}}
{{- else -}}
{{- printf "https://raw.githubusercontent.com/GothenburgBitFactory/taskchampion-sync-server/v%s/postgres/schema.sql" .Chart.AppVersion -}}
{{- end -}}
{{- end -}}
{{- define "taskchampion-sync-server.postgres-secret-name" -}}
{{- printf "%s-connection" .Release.Name -}}
{{- end -}}

View File

@ -0,0 +1,145 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "taskchampion-sync-server.fullname" . }}
labels:
{{- include "taskchampion-sync-server.labels" . | nindent 4 }}
spec:
{{- if and (eq .Values.postgres.enabled true) .Values.replicas.enabled }}
replicas: {{ .Values.replicas.count }}
{{- else }}
replicas: 1
{{- end }}
selector:
matchLabels:
{{- include "taskchampion-sync-server.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "taskchampion-sync-server.selectorLabels" . | nindent 8 }}
spec:
{{- if .Values.serviceAccount.create }}
serviceAccountName: {{ include "taskchampion-sync-server.fullname" . }}
{{- else if .Values.serviceAccount.name }}
serviceAccountName: {{ .Values.serviceAccount.name }}
{{- end }}
securityContext:
{{- toYaml .Values.securityContext | nindent 8 }}
{{- if and .Values.postgres.enabled .Values.postgres.initContainer.enabled }}
initContainers:
- name: postgres-init
image: "{{ .Values.postgres.initContainer.image }}"
imagePullPolicy: {{ .Values.postgres.initContainer.imagePullPolicy }}
env:
- name: PGURI
valueFrom:
secretKeyRef:
name: {{ include "taskchampion-sync-server.postgres-secret-name" . }}
key: connection
- name: SCHEMA_URL
value: {{ include "taskchampion-sync-server.schema-url" . | quote }}
{{- if .Values.clientIdSecret }}
- name: CLIENT_IDS
valueFrom:
secretKeyRef:
name: {{ .Values.clientIdSecret }}
key: client-ids
{{- end }}
command:
- sh
- -c
- |
set -e
until pg_isready -d "$PGURI"; do
echo 'Waiting for PostgreSQL...'
sleep 2
done
echo "Downloading schema from ${SCHEMA_URL}..."
wget -qO /tmp/schema.sql "$SCHEMA_URL" || {
echo 'Failed to download schema - continuing with main container'
exit 0
}
psql "$PGURI" -f /tmp/schema.sql || {
echo 'Schema execution failed (SQL error) - continuing with main container'
exit 0
}
echo 'Schema executed successfully'
if [ -n "$CLIENT_IDS" ]; then
echo "Inserting client IDs..."
IFS=','
for client_id in $CLIENT_IDS; do
client_id=$(echo "$client_id" | tr -d ' ')
[ -z "$client_id" ] && continue
psql "$PGURI" -c "INSERT INTO clients (client_id) VALUES ('$client_id') ON CONFLICT (client_id) DO NOTHING;" || {
echo "Failed to insert client $client_id - continuing"
}
done
unset IFS
echo "Client ID insertion complete"
fi
{{- end }}
containers:
- name: taskchampion-sync-server
{{- if eq .Values.postgres.enabled true }}
image: "{{ .Values.image.repository }}-postgres:{{ .Values.image.tag }}"
{{- else }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
{{- end }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
{{- range $name, $value := .Values.env }}
- name: {{ $name }}
value: {{ $value | quote }}
{{- end }}
{{- if .Values.clientIdSecret }}
- name: CLIENT_ID
valueFrom:
secretKeyRef:
name: {{ .Values.clientIdSecret }}
key: client-ids
{{- end }}
{{- if eq .Values.sqlite.enabled true }}
- name: DATA_DIR
value: {{ .Values.sqlite.dataDir }}
{{- end }}
{{- if eq .Values.postgres.enabled true }}
- name: CONNECTION
valueFrom:
secretKeyRef:
name: {{ include "taskchampion-sync-server.postgres-secret-name" . }}
key: connection
{{- end }}
ports:
- name: http
containerPort: {{ .Values.service.targetPort }}
protocol: TCP
{{- with .Values.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- if eq .Values.sqlite.enabled true }}
volumeMounts:
- name: data
mountPath: {{ .Values.sqlite.dataDir }}
{{- end }}
{{- if eq .Values.sqlite.enabled true }}
volumes:
{{- if .Values.sqlite.existingPV }}
- name: data
persistentVolumeClaim:
claimName: {{ .Values.sqlite.existingPV }}
{{- else if .Values.sqlite.persistence.enabled }}
- name: data
persistentVolumeClaim:
claimName: {{ include "taskchampion-sync-server.fullname" . }}-pvc
{{- else }}
- name: data
emptyDir:
{{- if .Values.sqlite.emptyDir.sizeLimit }}
sizeLimit: {{ .Values.sqlite.emptyDir.sizeLimit }}
{{- end }}
{{- if .Values.sqlite.emptyDir.medium }}
medium: {{ .Values.sqlite.emptyDir.medium }}
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,57 @@
{{- if .Values.httpRoute.enabled }}
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: {{ include "taskchampion-sync-server.fullname" . }}
labels:
{{- include "taskchampion-sync-server.labels" . | nindent 4 }}
{{- with .Values.httpRoute.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
parentRefs:
{{- if .Values.httpRoute.parentRefs }}
{{- range .Values.httpRoute.parentRefs }}
- name: {{ .name }}
{{- if .namespace }}
namespace: {{ .namespace }}
{{- end }}
{{- if .sectionName }}
sectionName: {{ .sectionName }}
{{- end }}
{{- end }}
{{- else if .Values.httpRoute.gateway }}
- name: {{ .Values.httpRoute.gateway }}
{{- end }}
{{- $hostnames := .Values.httpRoute.hostnames }}
{{- if and (not $hostnames) .Values.httpRoute.host }}
{{- $hostnames = list .Values.httpRoute.host }}
{{- end }}
{{- if $hostnames }}
hostnames:
{{- range $hostnames }}
- {{ . | quote }}
{{- end }}
{{- end }}
rules:
{{- if .Values.httpRoute.rules }}
{{- range .Values.httpRoute.rules }}
- matches:
- path:
type: {{ .path.type | default "PathPrefix" }}
value: {{ .path.value | default "/" }}
backendRefs:
- name: {{ include "taskchampion-sync-server.fullname" $ }}
port: {{ .backendPort | default 8080 }}
{{- end }}
{{- else }}
- matches:
- path:
type: PathPrefix
value: {{ .Values.httpRoute.path | default "/" }}
backendRefs:
- name: {{ include "taskchampion-sync-server.fullname" . }}
port: {{ .Values.httpRoute.port | default 8080 }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,33 @@
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "taskchampion-sync-server.fullname" . }}
labels:
{{- include "taskchampion-sync-server.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.className }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- toYaml .Values.ingress.tls | nindent 4 }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ . | quote }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {{ include "taskchampion-sync-server.fullname" $ }}
port:
number: {{ $.Values.service.port }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,17 @@
{{- if and (eq .Values.sqlite.enabled true) .Values.sqlite.persistence.enabled (not .Values.sqlite.existingPV) }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ include "taskchampion-sync-server.fullname" . }}-pvc
labels:
{{- include "taskchampion-sync-server.labels" . | nindent 4 }}
spec:
accessModes:
- {{ .Values.sqlite.persistence.accessMode }}
resources:
requests:
storage: {{ .Values.sqlite.persistence.size }}
{{- if .Values.sqlite.persistence.storageClass }}
storageClassName: {{ .Values.sqlite.persistence.storageClass }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,11 @@
{{- if .Values.postgres.enabled }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "taskchampion-sync-server.postgres-secret-name" . }}
labels:
{{- include "taskchampion-sync-server.labels" . | nindent 4 }}
type: Opaque
data:
connection: {{ include "taskchampion-sync-server.postgres-connection" . | b64enc }}
{{- end }}

View File

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "taskchampion-sync-server.fullname" . }}
labels:
{{- include "taskchampion-sync-server.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: {{ .Values.service.targetPort }}
protocol: TCP
name: http
selector:
{{- include "taskchampion-sync-server.selectorLabels" . | nindent 4 }}

View File

@ -0,0 +1,38 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "taskchampion-sync-server.fullname" . }}
labels:
{{- include "taskchampion-sync-server.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ include "taskchampion-sync-server.fullname" . }}-secret-manager
labels:
{{- include "taskchampion-sync-server.labels" . | nindent 4 }}
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create", "get", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ include "taskchampion-sync-server.fullname" . }}-secret-binding
labels:
{{- include "taskchampion-sync-server.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ include "taskchampion-sync-server.fullname" . }}-secret-manager
subjects:
- kind: ServiceAccount
name: {{ include "taskchampion-sync-server.fullname" . }}
namespace: {{ .Release.Namespace }}
{{- end -}}

View File

@ -0,0 +1,7 @@
{{- if and (eq .Values.sqlite.enabled false) (eq .Values.postgres.enabled false) -}}
{{- fail "ERROR: Exactly one storage backend must be enabled. Either sqlite.enabled or postgres.enabled must be true." -}}
{{- end -}}
{{- if and (eq .Values.sqlite.enabled true) (eq .Values.postgres.enabled true) -}}
{{- fail "ERROR: Only one storage backend can be enabled. Both sqlite.enabled and postgres.enabled cannot be true at the same time." -}}
{{- end -}}

View File

@ -0,0 +1,136 @@
# Override the chart name used in resource names
nameOverride: ""
# Override the full resource name (takes precedence over nameOverride)
fullnameOverride: ""
# Image configuration
image:
repository: ghcr.io/gothenburgbitfactory/taskchampion-sync-server
tag: "0.7.0"
pullPolicy: IfNotPresent
pullSecrets: []
# Existing secret containing client IDs (comma-separated UUIDs)
# Expected key: client-ids
clientIdSecret: ""
# Environment variables passed directly to the container
# NOTE: DATA_DIR and CONNECTION are set automatically based on backend
env:
RUST_LOG: info
LISTEN: "0.0.0.0:8080"
CREATE_CLIENTS: "true"
# Service configuration
service:
type: ClusterIP
port: 8080
targetPort: 8080
# Ingress configuration
ingress:
enabled: false
className: ""
annotations: {}
hosts: []
tls: []
# HTTPRoute configuration (Kubernetes Gateway API)
httpRoute:
enabled: false
annotations: {}
# List of parent gateway references.
# name is required; namespace and sectionName are optional.
parentRefs: []
# parentRefs:
# - name: my-gateway
# namespace: gateway-system # optional — cross-namespace gateway reference
# sectionName: https # optional — targets a specific listener on the gateway
# List of hostnames the route applies to.
hostnames: []
# hostnames:
# - tasks.example.com
# - tasks.internal.example.com
# List of routing rules. Each rule matches a path and forwards to this chart's Service.
# When empty, falls back to the deprecated path/port fields below.
rules: []
# rules:
# - path:
# type: PathPrefix # PathPrefix or Exact
# value: /
# backendPort: 8080
# Deprecated: use parentRefs instead
gateway: ""
# Deprecated: use hostnames instead
host: ""
# Deprecated: use rules instead
path: "/"
port: 8080
# Resource limits and requests
resources: {}
# limits:
# memory: 128Mi
# cpu: 100m
# requests:
# memory: 64Mi
# cpu: 50m
# Replica configuration (only applies when postgres is enabled)
replicas:
enabled: false
count: 1
# Security context for the pod
# NOTE: runAsUser and runAsGroup are intentionally unset.
# The Docker entrypoint requires root to chown the data directory and then
# drops privileges via su-exec to the taskchampion user (uid 1092).
securityContext:
fsGroup: 100
# SQLite backend configuration (mutually exclusive with postgres)
sqlite:
enabled: false
dataDir: /var/lib/taskchampion-sync-server/data
existingPV: ""
emptyDir:
sizeLimit: ""
medium: ""
persistence:
enabled: true
size: 1Gi
accessMode: ReadWriteOnce
storageClass: ""
existingClaim: ""
# Service account configuration
serviceAccount:
create: true # Default: automatically create service account
name: "" # Optional: use existing service account
annotations: {}
# PostgreSQL configuration
postgres:
enabled: false
existingSecret: "" # If empty, auto-create secret; if provided, use existing
# Individual connection components for building connection string
database: taskchampion
host: postgres
port: 5432
username: user
password: ""
# SSL mode for the PostgreSQL connection.
# Use 'disable' for internal cluster connections (no TLS).
# Options: disable, allow, prefer, require, verify-ca, verify-full
sslMode: disable
initContainer:
enabled: true
image: postgres:17-alpine
imagePullPolicy: IfNotPresent
# Override the schema URL. Defaults to the official schema for this chart's appVersion.
# e.g. https://raw.githubusercontent.com/GothenburgBitFactory/taskchampion-sync-server/v0.7.0/postgres/schema.sql
schemaUrl: ""

View File

@ -1,6 +1,6 @@
[package]
name = "taskchampion-sync-server-storage-postgres"
version = "0.7.0-pre"
version = "0.7.2-pre"
authors = ["Dustin J. Mitchell <dustin@v.igoro.us>"]
edition = "2021"
description = "Postgres backend for TaskChampion-sync-server"
@ -16,7 +16,7 @@ bb8.workspace = true
chrono.workspace = true
env_logger.workspace = true
log.workspace = true
taskchampion-sync-server-core = { path = "../core", version = "0.7.0-pre" }
taskchampion-sync-server-core = { path = "../core", version = "0.7.2-pre" }
thiserror.workspace = true
tokio-postgres.workspace = true
tokio.workspace = true

View File

@ -39,6 +39,26 @@ use uuid::Uuid;
#[cfg(test)]
mod testing;
/// An `ErrorSink` implementation that logs errors to the Rust log.
#[derive(Debug, Clone, Copy)]
pub struct LogErrorSink;
impl LogErrorSink {
fn new() -> Box<Self> {
Box::new(Self)
}
}
impl bb8::ErrorSink<tokio_postgres::Error> for LogErrorSink {
fn sink(&self, e: tokio_postgres::Error) {
log::error!("Postgres connection error: {e}");
}
fn boxed_clone(&self) -> Box<dyn bb8::ErrorSink<tokio_postgres::Error>> {
Self::new()
}
}
/// A storage backend which uses Postgres.
pub struct PostgresStorage {
pool: bb8::Pool<PostgresConnectionManager<MakeTlsConnector>>,
@ -49,7 +69,10 @@ impl PostgresStorage {
let connector = native_tls::TlsConnector::new()?;
let connector = postgres_native_tls::MakeTlsConnector::new(connector);
let manager = PostgresConnectionManager::new_from_stringlike(connection_string, connector)?;
let pool = bb8::Pool::builder().build(manager).await?;
let pool = bb8::Pool::builder()
.error_sink(LogErrorSink::new())
.build(manager)
.await?;
Ok(Self { pool })
}
}
@ -249,8 +272,13 @@ impl StorageTxn for Txn {
"UPDATE clients
SET latest_version_id = $1,
versions_since_snapshot = versions_since_snapshot + 1
WHERE client_id = $2 and latest_version_id = $3",
&[&version_id, &self.client_id, &parent_version_id],
WHERE client_id = $2 and (latest_version_id = $3 or latest_version_id = $4)",
&[
&version_id,
&self.client_id,
&parent_version_id,
&Uuid::nil(),
],
)
.await
.context("error updating latest_version_id")?;
@ -666,4 +694,22 @@ mod test {
})
.await
}
#[tokio::test]
/// When an add_version call specifies a `parent_version_id` that does not exist in the
/// DB, but no other versions exist, the call succeeds.
async fn test_add_version_no_history() -> anyhow::Result<()> {
with_db(async |connection_string, db_client| {
let storage = PostgresStorage::new(connection_string).await?;
let client_id = make_client(&db_client).await?;
let mut txn = storage.txn(client_id).await?;
let version_id = Uuid::new_v4();
let parent_version_id = Uuid::new_v4();
txn.add_version(version_id, parent_version_id, b"v1".to_vec())
.await?;
Ok(())
})
.await
}
}

View File

@ -1,6 +1,6 @@
[package]
name = "taskchampion-sync-server"
version = "0.7.0-pre"
version = "0.7.2-pre"
authors = ["Dustin J. Mitchell <dustin@mozilla.com>"]
edition = "2021"
publish = false

View File

@ -1,6 +1,6 @@
[package]
name = "taskchampion-sync-server-storage-sqlite"
version = "0.7.0-pre"
version = "0.7.2-pre"
authors = ["Dustin J. Mitchell <dustin@mozilla.com>"]
edition = "2021"
description = "SQLite backend for TaskChampion-sync-server"
@ -9,7 +9,7 @@ repository = "https://github.com/GothenburgBitFactory/taskchampion-sync-server"
license = "MIT"
[dependencies]
taskchampion-sync-server-core = { path = "../core", version = "0.7.0-pre" }
taskchampion-sync-server-core = { path = "../core", version = "0.7.2-pre" }
async-trait.workspace = true
uuid.workspace = true
anyhow.workspace = true

View File

@ -276,11 +276,12 @@ impl StorageTxn for Txn {
SET
latest_version_id = ?,
versions_since_snapshot = versions_since_snapshot + 1
WHERE client_id = ? and latest_version_id = ?",
WHERE client_id = ? and (latest_version_id = ? or latest_version_id = ?)",
params![
StoredUuid(version_id),
StoredUuid(self.client_id),
StoredUuid(parent_version_id)
StoredUuid(parent_version_id),
StoredUuid(Uuid::nil())
],
)
.context("Error updating client for new version")?;
@ -489,4 +490,21 @@ mod test {
Ok(())
}
#[tokio::test]
/// When an add_version call specifies a `parent_version_id` that does not exist in the
/// DB, but no other versions exist, the call succeeds.
async fn test_add_version_no_history() -> anyhow::Result<()> {
let tmp_dir = TempDir::new()?;
let storage = SqliteStorage::new(tmp_dir.path())?;
let client_id = Uuid::new_v4();
let mut txn = storage.txn(client_id).await?;
txn.new_client(Uuid::nil()).await?;
let version_id = Uuid::new_v4();
let parent_version_id = Uuid::new_v4();
txn.add_version(version_id, parent_version_id, b"v1".to_vec())
.await?;
Ok(())
}
}