diff --git a/.github/workflows/cd-cloud.yml b/.github/workflows/cd-cloud.yml
index b155624a..90a09dab 100644
--- a/.github/workflows/cd-cloud.yml
+++ b/.github/workflows/cd-cloud.yml
@@ -1,4 +1,4 @@
-name: Create docker images
+name: Create docker images (cloud)
on:
push:
diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml
index cf275cb8..5a529a6c 100644
--- a/.github/workflows/cd.yml
+++ b/.github/workflows/cd.yml
@@ -1,50 +1,101 @@
name: Create docker images
-on: [create]
+on:
+ push:
+ branches:
+ - master
+ - main
+ - dev
+ # Publish semver tags as releases.
+ tags: [ 'v*.*.*' ]
+ pull_request:
+ branches:
+ - master
+ - main
+ - dev
+ workflow_dispatch:
jobs:
build:
name: Build, push, and deploy
- if: ${{ startsWith(github.ref, 'refs/tags/v') }}
runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ packages: write
+ # This is used to complete the identity challenge
+ # with sigstore/fulcio when running outside of PRs.
+ id-token: write
strategy:
matrix:
db-type: [postgresql]
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v5
- - name: Set env
- run: |
- echo "NOW=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV
-
- - name: Generate tags
- id: generate_tags
- run: |
- echo "tag_patch=$(echo ${{ matrix.db-type }})-${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
- echo "tag_minor=$(echo ${{ matrix.db-type }})-$(echo ${GITHUB_REF#refs/tags/} | cut -d. -f1,2)" >> $GITHUB_ENV
- echo "tag_major=$(echo ${{ matrix.db-type }})-$(echo ${GITHUB_REF#refs/tags/} | cut -d. -f1)" >> $GITHUB_ENV
- echo "tag_latest=$(echo ${{ matrix.db-type }})-latest" >> $GITHUB_ENV
+ # Install the cosign tool except on PR
+ # https://github.com/sigstore/cosign-installer
+ - name: Install cosign
+ if: github.event_name != 'pull_request'
+ uses: sigstore/cosign-installer@v3
- - uses: mr-smithers-excellent/docker-build-push@v6
- name: Build & push Docker image to ghcr.io for ${{ matrix.db-type }}
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+
+ - name: Log into registry docker.io
+ if: github.event_name != 'pull_request' && github.repository == 'umami-software/umami'
+ uses: docker/login-action@v3
with:
- image: umami
- tags: ${{ env.tag_major }}, ${{ env.tag_minor }}, ${{ env.tag_patch }}, ${{ env.tag_latest }}
- buildArgs: DATABASE_TYPE=${{ matrix.db-type }}
- registry: ghcr.io
- multiPlatform: true
- platform: linux/amd64,linux/arm64
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- - uses: mr-smithers-excellent/docker-build-push@v6
- name: Build & push Docker image to docker.io for ${{ matrix.db-type }}
- with:
- image: umamisoftware/umami
- tags: ${{ env.tag_major }}, ${{ env.tag_minor }}, ${{ env.tag_patch }}, ${{ env.tag_latest }}
- buildArgs: DATABASE_TYPE=${{ matrix.db-type }}
registry: docker.io
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
+
+ - name: Log into ghcr registry
+ if: github.event_name != 'pull_request'
+ uses: docker/login-action@v3
+ with:
+ registry: ghcr.io
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Extract Docker metadata
+ id: meta
+ uses: docker/metadata-action@v5
+ with:
+ images: |
+ umamisoftware/umami,enable=${{ github.repository == 'umami-software/umami' }}
+ ghcr.io/${{ github.repository }}
+ flavor: |
+ latest=auto
+ prefix=${{ matrix.db-type }}-
+ tags: |
+ type=ref,event=branch
+ type=ref,event=pr
+
+ # output 1.1.2
+ type=semver,pattern={{version}}
+ # output 1.1
+ type=semver,pattern={{major}}.{{minor}}
+ # output 1
+ type=semver,pattern={{major}}
+
+ - name: Build and push Docker image
+ id: build-and-push
+ uses: docker/build-push-action@v6
+ with:
+ context: .
+ platforms: linux/amd64,linux/arm64
+ build-args: DATABASE_TYPE=${{ matrix.db-type }}
+ push: ${{ github.event_name != 'pull_request' }}
+ tags: ${{ steps.meta.outputs.tags }}
+ labels: ${{ steps.meta.outputs.labels }}
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
+
+ # Sign the resulting Docker image digest except on PRs.
+ - name: Sign the published Docker image
+ if: ${{ github.event_name != 'pull_request' }}
+ env:
+ TAGS: ${{ steps.meta.outputs.tags }}
+ DIGEST: ${{ steps.build-and-push.outputs.digest }}
+ run: echo "${TAGS}" | xargs -I {} cosign sign --yes "{}@${DIGEST}"
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 88a922e3..eee0a02d 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -14,11 +14,16 @@ jobs:
strategy:
matrix:
include:
- - node-version: 18.18
- db-type: postgresql
+ - node-version: 18.18
+ pnpm-version: 10
+ db-type: postgresql
steps:
- uses: actions/checkout@v4
+ - uses: pnpm/action-setup@v4 # required so that setup-node will work
+ with:
+ version: ${{ matrix.pnpm-version }}
+ run_install: false
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
diff --git a/src/components/input/SettingsButton.tsx b/src/components/input/SettingsButton.tsx
index 275fab07..23ad91d3 100644
--- a/src/components/input/SettingsButton.tsx
+++ b/src/components/input/SettingsButton.tsx
@@ -10,7 +10,15 @@ import {
MenuSection,
} from '@umami/react-zen';
import { useMessages, useLoginQuery, useNavigation, useConfig } from '@/components/hooks';
-import { LogOut, LockKeyhole, Settings, UserCircle, LifeBuoy, BookText } from '@/components/icons';
+import {
+ LogOut,
+ LockKeyhole,
+ Settings,
+ UserCircle,
+ LifeBuoy,
+ BookText,
+ ExternalLink,
+} from '@/components/icons';
import { DOCS_URL } from '@/lib/constants';
export function SettingsButton() {
@@ -54,7 +62,11 @@ export function SettingsButton() {
id="/docs"
icon={}
label={formatMessage(labels.documentation)}
- />
+ >
+
+
+
+
}
diff --git a/src/lib/constants.ts b/src/lib/constants.ts
index c6c63c70..af617458 100644
--- a/src/lib/constants.ts
+++ b/src/lib/constants.ts
@@ -361,8 +361,10 @@ export const MAP_FILE = '/datamaps.world.json';
export const ISO_COUNTRIES = {
ANT: 'AN',
ARE: 'AE',
+ AUT: 'AT',
BLM: 'BL',
CHE: 'CH',
+ DEU: 'DE',
ESH: 'EH',
ESP: 'ES',
FSM: 'FM',