diff --git a/.env.example b/.env.example index b70db497..d7f49962 100644 --- a/.env.example +++ b/.env.example @@ -1,8 +1,7 @@ -# Google credentials -OAUTH_URI= -OAUTH_CLIENT_ID= -OAUTH_SCOPE=https://www.googleapis.com/auth/drive.appdata +# Backend host, usually /api if hosted locally and used via proxy +# See https://github.com/simonwep/genesis +OCULAR_GENESIS_HOST=/api -# Ackee tracker details -ACKEE_HOST= -ACKEE_DOMAIN_ID= +# Optional, pre-filled login credentials for local testing +OCULAR_TEST_USERNAME= +OCULAR_TEST_PASSWORD= diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bff7937c..86376138 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,6 +2,11 @@ name: CI on: push +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + OCULAR_GENESIS_HOST: /api + jobs: build: name: Build app @@ -25,12 +30,6 @@ jobs: run: pnpm run lint - name: Build - env: - OAUTH_URI: ${{ secrets.OAUTH_URI }} - OAUTH_SCOPE: ${{ secrets.OAUTH_SCOPE }} - OAUTH_CLIENT_ID: ${{ secrets.OAUTH_CLIENT_ID }} - ACKEE_HOST: ${{ secrets.ACKEE_HOST }} - ACKEE_DOMAIN_ID: ${{ secrets.ACKEE_DOMAIN_ID }} run: pnpm run build - name: Upload artifact @@ -40,26 +39,40 @@ jobs: name: app path: dist - deploy: - name: Deploy app to GitHub Pages - runs-on: ubuntu-latest + build_docker: + if: startsWith(github.event.ref, 'refs/tags/v') + name: Build and publish docker image needs: build - if: github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + permissions: + contents: read + packages: write steps: - - uses: actions/checkout@v3 - - name: Download artifact - uses: actions/download-artifact@v3 + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Log in to the Container registry + uses: docker/login-action@v3 with: - name: app - path: dist + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - - name: Pre-Deploy - run: | - cp dist/index.html dist/404.html - touch dist/.nojekyll + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=semver,pattern=v{{version}} + type=semver,pattern=v{{major}}.{{minor}} - - name: Deploy - uses: JamesIves/github-pages-deploy-action@v4 + - name: Build and push Docker image + uses: docker/build-push-action@v5 with: - branch: gh-pages - folder: dist + push: true + provenance: false + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + build-args: | + OCULAR_GENESIS_HOST=${{ env.OCULAR_GENESIS_HOST }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d43dc911..916fb29f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,15 +1,15 @@ -### Commit guidelines +## Commit guidelines This project *strictly* follows [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/). Check out [their explanation](https://www.conventionalcommits.org/en/v1.0.0/#summary) of how to use it. In this project we have the following scopes / types: -#### Scopes +### Scopes * `core` - Core code, anything app / user-facing related. * `setup` - Anything *only* relevant to the build-process / CI. -#### Types +### Types * `feat` - A new feature. * `refactor` - A refactoring. diff --git a/Dockerfile b/Dockerfile index 4d196325..5c5f9205 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,6 @@ -FROM node:18-alpine AS build +FROM node:20-alpine AS build -ARG OAUTH_URI -ARG OAUTH_CLIENT_ID -ARG OAUTH_SCOPE -ARG ACKEE_HOST -ARG ACKEE_DOMAIN_ID +ARG OCULAR_GENESIS_HOST ENV PNPM_HOME="/pnpm" ENV PATH="$PNPM_HOME:$PATH" diff --git a/README.md b/README.md index 34616cbe..c47cee62 100644 --- a/README.md +++ b/README.md @@ -18,28 +18,25 @@ ### Features -- 🥳 Simple login via google. -- 🌚 Dark and light theme. -- 💻 Installable (PWA). -- ⬆️ Import your data from Google sheet's annual planner. -- ⬇️ Export your data as a single `.json`-file. -- 🕰 Track budgets across year. +- 🦾 Self-hosted. +- 🕶️ Dark and light theme. +- 💻 Installable as a PWA. +- 🔼 Import your data from Google sheet's annual planner. +- 🛠️ Export your data as a single `.json`-file. +- 🎇 Track budgets across multiple years. - 🙈 Privacy mode for when you're in a public place. -- 🪩 Simple and straight-forward UI. +- ⚡️ Simple and straight-forward UI. > Check out the [demo](https://ocular.reinisch.io#demo)! +> Looking for the legacy google-app based version? Check out the [legacy](https://github.com/simonwep/ocular/tree/legacy) branch. ### Summary A small budgeting app as an alternative to Google sheet's annual budget planner. The goal of the app is **not** to track individual expenses, work with multiple currencies at a time or anything related (if you're looking for something like this, check out [firefly-iii](https://www.firefly-iii.org/)). -This app comes without any backend and all your data is stored in your google-drive account as an app (no worry - you can always export your data in the app). -**This app does not have access to anything else except its own files**. -The (latest) version I use is automatically deployed to [ocular.reinisch.io](https://ocular.reinisch.io) - but feel free to [set it up yourself](#development)! - -> **Attention:** It's currently **not** possibly to sync the app with your personal gmail account due to the google-cloud app not being verified yet. -> You can still use it and download / upload your data or [deploy it yourself](#development) (which is even cooler!). +This app comes with its own backend (by using [genesis](https://github.com/simonwep/genesis)), so the only thing you need to do is to host it somewhere. +Your data stays on your server and is not shared with anyone else. ### State of this project @@ -47,39 +44,20 @@ I consider the current state of it as the MVP for personal use. But I'm planning on adding more [features](https://github.com/Simonwep/ocular/issues) - I'm not planning of making it any more in-depth as it already is, planned features may only include adding a way to define goals or general improvements for mobile usage. As I already said, if you're looking for an in-depth tool to manage your finances check out [firefly](https://www.firefly-iii.org/)! -### Contributing - -If you want to work on this, make sure to out the [contributing guidelines](CONTRIBUTING.md) :) -Furthermore this project *does not* have releases. -Because of its simplicity the master branch is considered stable and any new feature will directly be merged into it. - -#### Development - -This app requires [NodeJS LTS](https://nodejs.org/en/) and uses [vite](https://vitejs.dev/) as builder. -You can build and preview the app using the following commands: +### Development -```sh -npm run build -npm run preview -``` +This app uses [genesis](https://github.com/simonwep/genesis) as generic backend. +Go to the [genesis](https://github.com/simonwep/genesis) repository and follow the instructions to set it up first. -To work on it simply run `npm run dev`. +To run the frontend make sure you have the latest [node LTS](https://nodejs.org/en/) installed, as well as [pnpm](https://pnpm.io/). +You can then start the frontend by running `pnpm run dev` in the root directory. -#### Production +### Production -To run this app in production and to add cloud connectivity, you'll need a [Google Cloud App](https://console.cloud.google.com) with -the `drive.appdata` scope. +This app is deployed using [docker-compose](https://docs.docker.com/compose/). +See [ocular-docker](https://github.com/simonwep/ocular-docker) for deployment. -After you've set up your app fill copy the [.env.example](.env.example) to `.env` and fill in your credentials. - - -##### Using docker - -This project can be build as a docker-image, that serves the app via nginx. -You can build and run it via: - -```sh -docker build -t ocular . && docker run -p 8080:80 ocular -``` +### Contributing -Ocular should then be available under [localhost:8080](http://localhost:8080) +If you want to work on this, make sure to out the [contributing guidelines](CONTRIBUTING.md) :) +Other than that, follow the steps under [development](#development) to get started. \ No newline at end of file diff --git a/package.json b/package.json index 5e6fb451..bf4fd9e7 100644 --- a/package.json +++ b/package.json @@ -19,12 +19,11 @@ "lint:i18n:fix": "pnpm run lint:i18n --fix", "lint": "pnpm run lint:i18n && pnpm run lint:src", "lint:fix": "pnpm run lint:i18n:fix && pnpm run lint:src:fix", - "test:ci": "pnpm run build && pnpm run lint:fix", + "test:ci": "pnpm run lint:fix && pnpm run build", "gen:icons": "node scripts/icons.js" }, "dependencies": { "@popperjs/core": "2.11.8", - "ackee-tracker": "5.1.0", "echarts": "5.4.3", "li18nt": "5.0.0", "papaparse": "5.4.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fb3fdef3..23f31fcb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,9 +8,6 @@ dependencies: '@popperjs/core': specifier: 2.11.8 version: 2.11.8 - ackee-tracker: - specifier: 5.1.0 - version: 5.1.0 echarts: specifier: 5.4.3 version: 5.4.3 @@ -153,7 +150,7 @@ packages: '@babel/helper-compilation-targets': 7.22.5(@babel/core@7.22.5) '@babel/helper-module-transforms': 7.22.5 '@babel/helpers': 7.22.5 - '@babel/parser': 7.22.5 + '@babel/parser': 7.23.0 '@babel/template': 7.22.5 '@babel/traverse': 7.22.5 '@babel/types': 7.22.5 @@ -246,7 +243,7 @@ packages: '@babel/helper-plugin-utils': 7.22.5 debug: 4.3.4 lodash.debounce: 4.0.8 - resolve: 1.22.2 + resolve: 1.22.8 semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -1312,7 +1309,7 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.22.5 - '@babel/parser': 7.22.5 + '@babel/parser': 7.23.0 '@babel/types': 7.22.5 dev: true @@ -1326,7 +1323,7 @@ packages: '@babel/helper-function-name': 7.22.5 '@babel/helper-hoist-variables': 7.22.5 '@babel/helper-split-export-declaration': 7.22.5 - '@babel/parser': 7.22.5 + '@babel/parser': 7.23.0 '@babel/types': 7.22.5 debug: 4.3.4 globals: 11.12.0 @@ -1721,7 +1718,7 @@ packages: builtin-modules: 3.3.0 deepmerge: 4.3.1 is-module: 1.0.0 - resolve: 1.22.2 + resolve: 1.22.8 rollup: 2.79.1 dev: true @@ -2113,12 +2110,6 @@ packages: /@vue/shared@3.3.7: resolution: {integrity: sha512-N/tbkINRUDExgcPTBvxNkvHGu504k8lzlNQRITVnm6YjOjwa4r0nnbd4Jb01sNpur5hAllyRJzSK5PvB9PPwRg==} - /ackee-tracker@5.1.0: - resolution: {integrity: sha512-A7iKkGyUnEXuOzxultQB7hnm4bStYCo1c38MYRRihBfqUP8AImhtZOODb00t9xrXs/BTsg06bz1MKpXeMs9sYw==} - dependencies: - platform: 1.3.6 - dev: false - /acorn-jsx@5.3.2(acorn@8.9.0): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -3986,10 +3977,6 @@ packages: engines: {node: '>=8.6'} dev: true - /platform@1.3.6: - resolution: {integrity: sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==} - dev: false - /postcss-selector-parser@6.0.13: resolution: {integrity: sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==} engines: {node: '>=4'} @@ -4128,15 +4115,6 @@ packages: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} dev: true - /resolve@1.22.2: - resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==} - hasBin: true - dependencies: - is-core-module: 2.13.0 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - dev: true - /resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true diff --git a/src/app/App.vue b/src/app/App.vue index 09af885d..94bf8e2a 100644 --- a/src/app/App.vue +++ b/src/app/App.vue @@ -1,7 +1,7 @@