From bf4e6ea96f4449d88c797aad60f3b850a1081a4e Mon Sep 17 00:00:00 2001 From: Gavin Mogan Date: Sat, 6 Sep 2025 00:49:55 -0700 Subject: [PATCH 1/4] Migrate to docker actions Originally just wanted to add the standard opencontainer labels that docker/metadata provide but with "mr-smithers-excellent" seemed to only half implement docker support, and a higher risk than docker for supply chain issues, so I went all out and also added cosign to sign the images. Docker metadata tags supports all the custom code to create version tags, out of the box and fully maintained Also dropped the manual workflow, just merged it into cd.yml since you can select tags when you manual dispatch, and thats less to maintain --- .github/workflows/cd-cloud.yml | 2 +- .github/workflows/cd-manual.yml | 58 ----------------- .github/workflows/cd.yml | 109 +++++++++++++++++++++++--------- 3 files changed, 81 insertions(+), 88 deletions(-) delete mode 100644 .github/workflows/cd-manual.yml 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-manual.yml b/.github/workflows/cd-manual.yml deleted file mode 100644 index 1f8651fa..00000000 --- a/.github/workflows/cd-manual.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: Create docker images (manual) - -on: - workflow_dispatch: - inputs: - version: - type: string - description: Version - required: true - -jobs: - build: - name: Build, push, and deploy - runs-on: ubuntu-latest - - strategy: - matrix: - db-type: [postgresql, mysql] - - steps: - - uses: actions/checkout@v3 - - - name: Extract version parts from input - id: extract_version - run: | - echo "version=$(echo ${{ github.event.inputs.version }})" >> $GITHUB_ENV - echo "major=$(echo ${{ github.event.inputs.version }} | cut -d. -f1)" >> $GITHUB_ENV - echo "minor=$(echo ${{ github.event.inputs.version }} | cut -d. -f2)" >> $GITHUB_ENV - - - name: Generate tags - id: generate_tags - run: | - echo "tag_major=$(echo ${{ matrix.db-type }}-${{ env.major }})" >> $GITHUB_ENV - echo "tag_minor=$(echo ${{ matrix.db-type }}-${{ env.major }}.${{ env.minor }})" >> $GITHUB_ENV - echo "tag_patch=$(echo ${{ matrix.db-type }}-${{ env.version }})" >> $GITHUB_ENV - echo "tag_latest=$(echo ${{ matrix.db-type }}-latest)" >> $GITHUB_ENV - - - uses: mr-smithers-excellent/docker-build-push@v6 - name: Build & push Docker image to ghcr.io for ${{ matrix.db-type }} - 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 }} \ No newline at end of file diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index f67f51c3..051d24a2 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, mysql] 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: + 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: - 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 }} + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v5 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 }} \ No newline at end of file + 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}" From b2c829a077fc388bb17e7c045a702be507b08dc0 Mon Sep 17 00:00:00 2001 From: Nick Maynard Date: Wed, 17 Sep 2025 21:37:57 +0100 Subject: [PATCH 2/4] Add setup-pnpm to hopefully fix CI tests etc. --- .github/workflows/ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 478e5ad1..d2e027cf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,12 +19,18 @@ jobs: matrix: include: - node-version: 18.18 + pnpm-version: 10 db-type: postgresql - node-version: 18.18 + pnpm-version: 10 db-type: mysql 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: From 7d9fe30626a0251884cc33a31d408cd93117e2ed Mon Sep 17 00:00:00 2001 From: Panagiotis Date: Sun, 21 Sep 2025 22:56:59 +0300 Subject: [PATCH 3/4] Resolve IPv6 address destruction --- src/lib/detect.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/lib/detect.ts b/src/lib/detect.ts index ee9d2603..17fb574c 100644 --- a/src/lib/detect.ts +++ b/src/lib/detect.ts @@ -108,6 +108,14 @@ function decodeHeader(s: string | undefined | null): string | undefined | null { return Buffer.from(s, 'latin1').toString('utf-8'); } +function removePortFromIP(ip: string = "") { + const split = ip.split(":"); + + // Assuming ip is a valid IPv4/IPv6 address, 3 colons is the minumum for IPv6 + const ipv4 = split.length - 1 < 3; + return ipv4 ? split[0] : ip; +} + export async function getLocation(ip: string = '', headers: Headers, hasPayloadIP: boolean) { // Ignore local ips if (await isLocalhost(ip)) { @@ -141,7 +149,7 @@ export async function getLocation(ip: string = '', headers: Headers, hasPayloadI } // When the client IP is extracted from headers, sometimes the value includes a port - const cleanIp = ip?.split(':')[0]; + const cleanIp = removePortFromIP(ip); const result = global[MAXMIND].get(cleanIp); if (result) { From cb209eee8162d3cf80edbc5d5b8a2472e42eb9b4 Mon Sep 17 00:00:00 2001 From: Tobias Kronthaler Date: Tue, 23 Sep 2025 10:09:58 +0200 Subject: [PATCH 4/4] Fix map display for DACH --- src/lib/constants.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib/constants.ts b/src/lib/constants.ts index 6192f342..75691d05 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -448,8 +448,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',