Compare commits

..

9 Commits

Author SHA1 Message Date
Constantin Graf
5837b5d60c Add on premise build 2025-08-12 16:20:50 +02:00
Constantin Graf
f68f05d1aa Updated the PR template 2025-07-31 14:01:17 +02:00
Gregor Vostrak
8fdc4c1219 add contributing notice that you need to run the format command 2025-07-31 14:01:17 +02:00
Gregor Vostrak
93148299a9 add CONTRIBUTING.md 2025-07-31 14:01:17 +02:00
Constantin Graf
78d2ea1a25 Add API doc description for chart endpoints 2025-07-31 13:43:00 +02:00
Constantin Graf
14f559c4c2 Removed FORWARD_WEB_PORT from local setup 2025-07-31 13:42:37 +02:00
Gregor Vostrak
61fd2b1187 update font-face file names for font loading 2025-07-31 12:08:51 +02:00
Gregor Vostrak
9ea3c5dc29 fix font embeds #864 2025-07-31 11:53:32 +02:00
Gregor Vostrak
cb30487a21 add format check, update prettier rules, apply rules consistently 2025-07-31 11:53:00 +02:00
12 changed files with 329 additions and 4121 deletions

View File

@@ -80,8 +80,7 @@ GOTENBERG_URL=http://gotenberg:3000
# Local setup
NGINX_HOST_NAME=solidtime.test
NETWORK_NAME=reverse-proxy-docker-traefik_routing
FORWARD_DB_PORT=5432
FORWARD_WEB_PORT=8083
FORWARD_DB_PORT=54329
VITE_HOST_NAME=vite.solidtime.test
VITE_APP_NAME="${APP_NAME}"
#SAIL_XDEBUG_MODE=develop,debug,coverage

View File

@@ -1,8 +1,11 @@
<!--
This project is early stage. The structure and APIs are still subject to change and not stable.
Therefore, we do not currently accept any contributions, unless you are a member of the team.
## What does this PR do?
As soon as we feel comfortable enough that the application structure is stable enough, we will open up the project for contributions.
<!-- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. -->
We do accept contributions in the [documentation repository](https://github.com/solidtime-io/docs) f.e. to add new self-hosting guides.
-->
- Fixes #XXXX (GitHub issue number)
## Checklist (DO NOT REMOVE)
- [ ] I read the [contributing guide](https://github.com/solidtime-io/solidtime/blob/main/CONTRIBUTING.md)
- [ ] I signed the [Contributor License Agreement](https://cla-assistant.io/solidtime-io/solidtime).
- [ ] I commented my code, particularly in hard-to-understand areas

216
.github/workflows/build-onpremise.yml vendored Normal file
View File

@@ -0,0 +1,216 @@
on:
push:
branches:
- main
- develop
tags:
- '*'
pull_request:
paths:
- '.github/workflows/build-onpremise.yml'
- 'docker/prod/**'
workflow_dispatch:
permissions:
packages: write
contents: read
attestations: write
id-token: write
env:
DOCKER_REPO: registry.on-premise.solidtime.io/solidtime/solidtime
name: Build - On Premise
jobs:
build:
strategy:
matrix:
include:
- runs-on: "ubuntu-24.04-arm"
platform: "linux/arm64"
- runs-on: "ubuntu-24.04"
platform: "linux/amd64"
runs-on: ${{ matrix.runs-on }}
timeout-minutes: 90
steps:
- name: "Check out code"
uses: actions/checkout@v4
with:
fetch-depth: 0 # Required for WyriHaximus/github-action-get-previous-tag
- name: "Get build"
id: release-build
run: echo "build=$(git rev-parse --short=8 HEAD)" >> "$GITHUB_OUTPUT"
- name: "Get Previous tag (normal push)"
id: previoustag
if: ${{ !startsWith(github.ref, 'refs/tags/v') }}
uses: "WyriHaximus/github-action-get-previous-tag@v1"
with:
prefix: "v"
- name: "Get version"
id: release-version
run: |
if ${{ !startsWith(github.ref, 'refs/tags/v') }}; then
if ${{ startsWith(steps.previoustag.outputs.tag, 'v') }}; then
version=$(echo "${{ steps.previoustag.outputs.tag }}" | cut -c 2-)
echo "app_version=${version}" >> "$GITHUB_OUTPUT"
else
echo "ERROR: No previous tag found";
exit 1;
fi
else
version=$(echo "${{ github.ref }}" | cut -c 12-)
echo "app_version=${version}" >> "$GITHUB_OUTPUT"
fi
- name: "Copy .env template for production"
run: |
cp .env.production .env
rm .env.production .env.ci .env.example
- name: "Add version to .env"
run: sed -i 's/APP_VERSION=0.0.0/APP_VERSION=${{ steps.release-version.outputs.app_version }}/g' .env
- name: "Add build to .env"
run: sed -i 's/APP_BUILD=0/APP_BUILD=${{ steps.release-build.outputs.build }}/g' .env
- name: "Output .env"
run: cat .env
- name: "Setup PHP with PECL extension"
uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
extensions: mbstring, dom, fileinfo, pgsql
- name: "Install dependencies"
run: composer install --no-dev --no-ansi --no-interaction --prefer-dist --ignore-platform-reqs --classmap-authoritative
if: steps.cache-vendor.outputs.cache-hit != 'true' # Skip if cache hit
- name: "Use Node.js"
uses: actions/setup-node@v4
with:
node-version: '20.x'
- name: "Checkout invoicing extension"
uses: actions/checkout@v4
with:
repository: solidtime-io/extension-invoicing
path: extensions/Invoicing
ssh-key: ${{ secrets.SSH_PRIVATE_KEY_INVOICING_EXTENSION }}
- name: "Install composer dependencies in invoicing extension"
run: cd extensions/Invoicing && composer install --no-dev --no-ansi --no-interaction --prefer-dist --ignore-platform-reqs --classmap-authoritative
- name: "Install npm dependencies in invoicing extension"
run: cd extensions/Invoicing && npm ci
- name: "Activate invoicing extension"
run: php artisan module:enable Invoicing
- name: "Install npm dependencies"
run: npm ci
- name: "Build"
run: npm run build
- name: "Prepare"
run: |
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: "Docker meta"
id: "meta"
uses: docker/metadata-action@v5
with:
images: |
${{ env.DOCKER_REPO }}
- name: "Login to solidtime OnPremise Registry"
uses: docker/login-action@v3
with:
registry: registry.on-premise.solidtime.io
username: ${{ secrets.ONPREMISE_USERNAME }}
password: ${{ secrets.ONPREMISE_TOKEN }}
- name: "Set up QEMU"
uses: docker/setup-qemu-action@v3
- name: "Set up Docker Buildx"
uses: docker/setup-buildx-action@v3
- name: "Build and push by digest"
id: build
uses: docker/build-push-action@v6
with:
context: .
file: docker/prod/Dockerfile
build-args: |
DOCKER_FILES_BASE_PATH=docker/prod/
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,"name=${{ env.DOCKER_REPO }}",push-by-digest=true,name-canonical=true,push=true
cache-from: type=gha
cache-to: type=gha,mode=max
- name: "Export digest"
run: |
mkdir -p ${{ runner.temp }}/digests
digest="${{ steps.build.outputs.digest }}"
touch "${{ runner.temp }}/digests/${digest#sha256:}"
- name: "Upload digest"
uses: actions/upload-artifact@v4
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: ${{ runner.temp }}/digests/*
if-no-files-found: error
retention-days: 1
merge:
runs-on: ubuntu-latest
timeout-minutes: 90
needs:
- build
steps:
- name: "Download digests"
uses: actions/download-artifact@v4
with:
path: ${{ runner.temp }}/digests
pattern: digests-*
merge-multiple: true
- name: "Login to solidtime OnPremise Registry"
uses: docker/login-action@v3
with:
registry: registry.on-premise.solidtime.io
username: ${{ secrets.ONPREMISE_USERNAME }}
password: ${{ secrets.ONPREMISE_TOKEN }}
- name: "Set up Docker Buildx"
uses: docker/setup-buildx-action@v3
- name: "Docker meta"
id: meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.DOCKER_REPO }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
- name: "Create manifest list and push"
working-directory: ${{ runner.temp }}/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.DOCKER_REPO }}@sha256:%s ' *)
- name: "Inspect image"
run: |
docker buildx imagetools inspect ${{ env.DOCKER_REPO }}:${{ steps.meta.outputs.version }}

81
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,81 @@
# Contributing to solidtime
Contributions are greatly apprecited, please make sure to read the rules and vision for solidtime before contributing.
## Rules
### Issues for Bugs, Discussions for Feature requests
In order to keep the issues of the repository clean we decided to only use them for bugs. Feature Requests and enhancement are handled in discussions. This also helps us to see which feature requests are popular as they can be upvoted.
### Only work on approved issues
To respect your time and help us manage contributions effectively, please open an issue or start a discussion and wait for approval before submitting a pull request (PR). This does not apply to tiny fixes or changes however, please keep in mind that we might not merge PRs for various reasons.
### Contributor License Agreement
You'll also notice that weve set up a [Contributor License Agreement (CLA)](https://cla-assistant.io/solidtime-io/solidtime), which must be signed before any PR can be merged. Dont worry - the process is quick and only takes a few clicks.
We want to be transparent about why we require the CLA and what it means for your contributions and the codebase. Thats why weve written a few paragraphs below outlining our plans and vision for solidtime in the **Vision** part of this document.
### Prevent Duplicate Work
Before you submit a new PR, make sure that none exists already. If you plan to work on an issue, make sure to let us and others know by commenting on the issue/discussion.
### Give context
Tell us what you thinking was behind the decisions you made while drafting the PR. Treat the PR itself as documentation for everyone who wants to go back and understand why certain decisions were made.
### Summarize your PR
Please make sure to include a short summary at the top of your PR to make it easy for us to quickly check what the PR is about, without looking at the code changes.
### Use Github Keywords and Auto-Link Issues
Use phrases like "Closes #123" or "Fixes #123" in the PR description to link the PR with the issue that you are adressing.
### Mention what you tested and how
Explain how you tested and validated the implementation.
### Keep Naming consistent
Look at existing code patterns and use naming conventions that already exist in the code base.
### Testing
We have an exhaustive test-suite of PHPUnit (Backend) and Playwright (Frontend) testing. Whereever applicable please make sure to write add tests to the codebase.
### Linting & Formatting
Make sure to run linting and formatting commands before you commit the changes.
For backend changes:
```
composer fix
composer analyse
```
For frontend changes:
```
npm run lint:fix
npm run format
```
## Vision
We started solidtime to provide an open infrastructure solution for time tracking—one that empowers teams and individuals to fully own their data, instead of depending on proprietary platforms. We believe infrastructure software should be open, accessible, and built to last. However, competing with established market leaders in this space requires long-term financial sustainability.
solidtime is licensed under the AGPL, which we believe is the best available license to strike a balance between openness and financial viability. The AGPL gives us, as the copyright holders, certain exclusive rights that we plan to leverage to fund development. To ensure we retain those rights across the entire codebase, we've put a CLA in place that contributors must sign before submitting code.
One of solidtimes key advantages is that it's built to be self-hostable. This makes it a great solution for organizations like governments, healthcare providers, and enterprises that are required to keep data on their own infrastructure due to regulations or internal policies. These organizations may need custom licenses, integrations, or modifications that aren't suitable for the open-source version. To support them, we offer relicensed versions of solidtime along with support plans.
Well also provide proprietary extensions for solidtime. These will be available to enterprise customers with support plans, but also to individual users or teams who dont need support, at much more accessible price points. For companies running solidtime on their own infrastructure, this is the easiest way to support the project while gaining additional functionality. While we plan to make it easier to build custom extensions in the future, our current APIs are still highly experimental.
Finally - and perhaps most importantly - we offer a hosted SaaS version called solidtime Cloud, for users who cant or dont want to run the software themselves. This version includes proprietary extensions, always runs the latest commit, and includes monitoring and billing features available exclusively on this hosted instance. We expect solidtime Cloud to play a critical role in funding the project long-term.
Having full control over the source codes licensing also gives us the ability to change the license of the main project in the future. That said, we have no plans to do so and would only consider it in extreme cases - for example, if a malicious actor were to directly compete with our hosted service in a way that threatens the sustainability of the project, the legal interpretation of AGPL changes in a way that would make it unreasonable to use for certain companies, or a new similar license gains wide-spread adoption. Regardless, solidtime will always remain free to self-host for individuals and companies who use it as part of their work, and all previous releases will remain licensed under AGPL.
If you are using the open-source version of solidtime and want to support us, the best way to do so is to spread the word.

View File

@@ -35,10 +35,9 @@ If you have a **feature request**, please [**create a discussion**](https://gith
## Contributing
This project is in a very early stage. The structure and APIs are still subject to change and not stable.
Therefore, we do not currently accept any contributions, unless you are a member of the team.
Please open an issue or start a discussion and wait for approval before submitting a pull request. This does not apply to tiny fixes or changes however, please keep in mind that we might not merge PRs for various reasons.
As soon as we feel comfortable enough that the application structure is stable enough, we will open up the project for contributions.
Please read the [CONTRIBUTING.md](./CONTRIBUTING.md) before sumbitting a Pull Request.
We do accept contributions in the [documentation repository](https://github.com/solidtime-io/docs) f.e. to add new self-hosting guides.

View File

@@ -14,6 +14,8 @@ use Illuminate\Http\JsonResponse;
class ChartController extends Controller
{
/**
* Get chart data for the weekly project overview.
*
* @throws AuthorizationException
*
* @operationId weeklyProjectOverview
@@ -31,6 +33,8 @@ class ChartController extends Controller
}
/**
* Get chart data for the latest tasks.
*
* @throws AuthorizationException
*
* @operationId latestTasks
@@ -48,6 +52,8 @@ class ChartController extends Controller
}
/**
* Get chart data for the last seven days.
*
* @throws AuthorizationException
*
* @operationId lastSevenDays
@@ -65,6 +71,8 @@ class ChartController extends Controller
}
/**
* Get chart data for the latest team activity.
*
* @throws AuthorizationException
*
* @operationId latestTeamActivity
@@ -81,6 +89,8 @@ class ChartController extends Controller
}
/**
* Get chart data for daily tracked hours.
*
* @throws AuthorizationException
*
* @operationId dailyTrackedHours
@@ -98,6 +108,8 @@ class ChartController extends Controller
}
/**
* Get chart data for total weekly time.
*
* @throws AuthorizationException
*
* @operationId totalWeeklyTime
@@ -115,6 +127,8 @@ class ChartController extends Controller
}
/**
* Get chart data for total weekly billable time.
*
* @throws AuthorizationException
*
* @operationId totalWeeklyBillableTime
@@ -132,6 +146,8 @@ class ChartController extends Controller
}
/**
* Get chart data for total weekly billable amount.
*
* @throws AuthorizationException
*
* @operationId totalWeeklyBillableAmount
@@ -154,6 +170,8 @@ class ChartController extends Controller
}
/**
* Get chart data for weekly history.
*
* @throws AuthorizationException
*
* @operationId weeklyHistory

View File

@@ -5,8 +5,6 @@ services:
dockerfile: Dockerfile
args:
WWWGROUP: '${WWWGROUP}'
ports:
- '${FORWARD_WEB_PORT:-8083}:80'
image: sail-8.3/app
labels:
- "traefik.enable=true"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

View File

@@ -163,10 +163,8 @@ body {
/* Inter Variable Font with browser compatibility considerations */
@font-face {
font-family: 'Inter';
src: url('/fonts/Inter-Variable.woff2') format('woff2 supports variations'),
url('/fonts/Inter-Variable.woff2') format('woff2-variations'),
url('/fonts/Inter-Variable.ttf') format('truetype supports variations'),
url('/fonts/Inter-Variable.ttf') format('truetype-variations');
src: url('/fonts/InterVariable.woff2') format('woff2'),
url('/fonts/InterVariable.ttf') format('truetype');
font-weight: 100 900;
font-style: normal;
font-display: swap;