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',