Skip to content

Upload source maps to Sentry for web#4279

Closed
dab246 wants to merge 6 commits intomasterfrom
features/upload-source-maps-web-to-sentry
Closed

Upload source maps to Sentry for web#4279
dab246 wants to merge 6 commits intomasterfrom
features/upload-source-maps-web-to-sentry

Conversation

@dab246
Copy link
Copy Markdown
Member

@dab246 dab246 commented Jan 27, 2026

Resolved

  • Upload source maps success
Screenshot 2026-01-27 at 15 02 28
  • Build docker image success
Screenshot 2026-01-27 at 14 46 38
  • Build gh-page skipped

Summary by CodeRabbit

  • Infrastructure & Build Improvements

    • CI simplified: consolidated build steps into reusable actions/workflows, replaced many step-level scripts, and unified image build/push flows; PR job-level Sentry env vars added.
    • Web builds now generate source maps but remove them from runtime artifacts before publishing.
  • New Features

    • Optional automated upload of source maps and release metadata to error-tracking when configured.
  • Chores

    • Added tooling and CI config to support source-map handling, artifact uploads, and release management.
  • Documentation

    • Added design notes on source-map and artifact handling.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jan 27, 2026

Walkthrough

Introduces a composite action (.github/actions/build-flutter-web) and a reusable workflow (.github/workflows/build-web-image.yaml) to centralize Flutter web build and Docker image creation. Adds SENTRY-related environment and config (pubspec, SENTRY_RELEASE), enables --source-maps generation in Flutter builds (script and Dockerfile), uploads source maps conditionally to Sentry and as GitHub artifacts, and removes .map files from runtime images. Removes multiple inline CI build/cleanup and PR-comment steps, replacing them with action/workflow-driven steps.

Possibly related PRs

  • linagora/tmail-flutter PR 4276 — modifies the Flutter web build to add the --source-maps flag, matching the source-map generation change in this PR.
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and accurately describes the main objective of the changeset: implementing source map upload to Sentry for the Flutter web build.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @.github/workflows/gh-pages.yaml:
- Around line 76-78: Guard the "Upload source maps to Sentry via
sentry_dart_plugin" step so it only runs when required Sentry secrets are
available and explicitly set a PR-scoped release: add an if condition checking
secrets (e.g. if: ${{ secrets.SENTRY_AUTH_TOKEN && secrets.SENTRY_ORG &&
secrets.SENTRY_PROJECT }}) on the step named "Upload source maps to Sentry via
sentry_dart_plugin", and populate the step's environment with SENTRY_AUTH_TOKEN,
SENTRY_ORG, SENTRY_PROJECT from secrets plus SENTRY_RELEASE set to a PR-scoped
value (e.g. use the pull_request number and commit SHA like pr-<number>-<sha>)
so the sentry_dart_plugin run uses the correct release and avoids failing on
forked PRs.

In @.github/workflows/image.yaml:
- Around line 51-57: The workflow uses unquoted shell variables in redirects
which triggers shellcheck SC2086; update the two run steps to quote the
destination variables so the redirects write to "$GITHUB_OUTPUT" and
"$GITHUB_ENV" (and likewise fix the other occurrences referenced around lines
144-150), and ensure the VERSION assignment and the SENTRY_RELEASE export still
reference the same symbols (VERSION, steps.version.outputs.VERSION,
SENTRY_RELEASE) but use the quoted forms for the redirect targets.

In `@Dockerfile`:
- Around line 10-11: Build is copying source maps into the runtime image via the
COPY build/web /usr/share/nginx/html step; remove .map files before they are
added to the final image by updating the Docker build flow: either add a step
that deletes map files from the build output (e.g., run a shell command to rm -f
build/web/**/*.map in a builder stage) before the COPY, or exclude *.map via
.dockerignore so COPY build/web /usr/share/nginx/html will not include source
maps. Ensure the change targets the COPY build/web /usr/share/nginx/html
operation so no .map files end up in the final nginx image.

@dab246 dab246 force-pushed the features/upload-source-maps-web-to-sentry branch from 79c8832 to 713889c Compare January 27, 2026 03:00
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @.github/workflows/gh-pages.yaml:
- Around line 94-96: The "Remove source maps before deploy" step currently uses
the command string "rm -rf build/web/*.js.map" which only deletes maps at the
top-level; change the run command to recursively delete all .js.map files (e.g.,
use a recursive glob like build/web/**/*.js.map or a find command) so source
maps in subdirectories are removed as well, keeping the step name "Remove source
maps before deploy" unchanged.

In @.github/workflows/image.yaml:
- Around line 63-66: The dev job uploads source maps via the step that runs
"dart run sentry_dart_plugin" but never deletes the .map files before the Docker
build, which causes source exposure; add a new step in the dev job immediately
after the "dart run sentry_dart_plugin" step (and before any Docker build/push
steps) that removes generated source maps (e.g., run: rm -f **/*.map or an
appropriate platform-safe command), or alternatively modify the Docker build
step to ensure the Dockerfile deletes .map files during image creation; target
the dev job steps around the "dart run sentry_dart_plugin" invocation and the
Docker build step to implement the removal.
- Around line 97-99: The workflow passes build-arg SENTRY_RELEASE but the
Dockerfile lacks ARG SENTRY_RELEASE so the build-arg is unused; either remove
SENTRY_RELEASE from the GitHub Actions workflow (remove the build-args line or
SENTRY_RELEASE entry) or add ARG SENTRY_RELEASE to the Dockerfile (declare ARG
SENTRY_RELEASE near other ARGs and use it in the Dockerfile as needed) so the
build-arg actually takes effect.
🧹 Nitpick comments (3)
.github/workflows/gh-pages.yaml (1)

68-71: Quote shell variables to prevent word splitting.

Per shellcheck SC2086, the $GITHUB_OUTPUT variable should be quoted.

🔧 Suggested fix
       run: |
         # Take the line containing the version, remove 'version: ', and discard the space.
         VERSION=$(grep '^version:' pubspec.yaml | sed 's/version: //;s/[[:space:]]//g')
-        echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
+        echo "VERSION=$VERSION" >> "$GITHUB_OUTPUT"
         echo "Version found: $VERSION"
Dockerfile (1)

16-17: Consider separating gzip compression from container startup.

Running gzip -k -r -f on every container start adds latency. If the assets are static, pre-compress them during the Docker build instead.

🔧 Suggested optimization
-CMD gzip -k -r -f /usr/share/nginx/html/ && nginx -g 'daemon off;'
+# Pre-compress static assets at build time
+RUN gzip -k -r -f /usr/share/nginx/html/
+
+CMD ["nginx", "-g", "daemon off;"]
.github/workflows/image.yaml (1)

160-162: LGTM on source map removal for release.

Good practice to remove source maps after uploading to Sentry but before building the Docker image. Consider using find for recursive removal to catch maps in subdirectories.

🔧 More robust removal
       # 🛡️ Remove source maps so the Docker image doesn't contain original code.
       - name: Remove source maps before Docker build
-        run: rm -rf build/web/*.js.map
+        run: find build/web -type f -name '*.map' -delete

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
.github/workflows/image.yaml (2)

98-108: Missing context: . will cause Docker build to fail.

The docker/build-push-action defaults to Git context (cloning the repo), which won't include the locally built build/web directory. The Dockerfile's COPY build/web /usr/share/nginx/html will fail because build/web doesn't exist in the Git-cloned context.

🔧 Suggested fix for both dev and release jobs
       - name: Build and push image
         uses: docker/build-push-action@v5
         with:
+          context: .
           push: true
           platforms: "linux/amd64,linux/arm64"

Apply to both the dev job (lines 98-108) and the release job (lines 195-205).


195-205: Missing context: . in release job as well.

Same issue as the dev job - without context: ., the Docker build will fail because the locally built build/web directory won't be accessible.

🤖 Fix all issues with AI agents
In @.github/workflows/gh-pages.yaml:
- Around line 85-93: The step "Upload source maps to Sentry" is using secrets in
a step-level if (SENTRY_AUTH_TOKEN), which is not allowed; move the secret into
a job-level env or output and change the step if to reference that env instead.
Concretely: add SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} (and
SENTRY_ORG/SENTRY_PROJECT if needed) at the job-level env, then update the step
"Upload source maps to Sentry" to use if: ${{ env.SENTRY_AUTH_TOKEN != '' &&
github.event.pull_request.head.repo.fork == false }} so the secret is not
referenced directly in the step-level if.
🧹 Nitpick comments (2)
.github/workflows/gh-pages.yaml (1)

65-72: Add error handling for version extraction.

If pubspec.yaml doesn't contain a version: line (unlikely but possible), VERSION will be empty, causing the Sentry upload to use an empty release identifier.

🔧 Suggested improvement
       - name: Read version from pubspec.yaml
         id: pubspec_version
         run: |
           # Take the line containing the version, remove 'version: ', and discard the space.
           VERSION=$(grep '^version:' pubspec.yaml | sed 's/version: //;s/[[:space:]]//g')
+          if [ -z "$VERSION" ]; then
+            echo "::error::Could not extract version from pubspec.yaml"
+            exit 1
+          fi
           echo "VERSION=$VERSION" >> "$GITHUB_OUTPUT"
           echo "Version found: $VERSION"
.github/workflows/image.yaml (1)

51-53: Quote $GITHUB_OUTPUT to satisfy shellcheck.

Line 53 uses unquoted $GITHUB_OUTPUT while line 57 correctly quotes it. This inconsistency triggers shellcheck SC2086.

🔧 Suggested fix
       - name: Read version from pubspec.yaml
         id: version
         run: |
           VERSION=$(grep '^version:' pubspec.yaml | sed 's/version: //')
-          echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
+          echo "VERSION=$VERSION" >> "$GITHUB_OUTPUT"

Copy link
Copy Markdown
Member

@chibenwa chibenwa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sometimes simpler is better

What's the issue with shipping source map directly in the image?

As such we make it more complex for community (and for us for on prem deployment!) to set up sentry. Also local debugging without source maps is harder.

I want @Crash-- opinion on this

@dab246
Copy link
Copy Markdown
Member Author

dab246 commented Jan 27, 2026

A few things to note:

  • We only upload the source map to Sentry after performing the flutter build web.
  • To upload the source map to Sentry, we can do it in two ways: using sentry_cli or sentry_dart_plugin (Sentry recommends using the latter).
  • Currently, the flutter build web is configured in the Dockerfile. Therefore, we must set up this Dockerfile.

I'm not a Docker expert, so changing the Dockerfile is quite complicated. If you have any suggestions for this, please comment on this PR.

@chibenwa
Copy link
Copy Markdown
Member

Have you looked at #4276 ?

@dab246
Copy link
Copy Markdown
Member Author

dab246 commented Jan 28, 2026

Have you looked at #4276 ?

I've looked at it, but what you've done is just flagging Flutter to create the .js.map source map file. You haven't uploaded the generated source map to Sentry yet. Doing it this way makes running it locally and deploying it for testing quite difficult.

@dab246 dab246 requested a review from chibenwa January 28, 2026 01:48
@hoangdat
Copy link
Copy Markdown
Member

hoangdat commented Jan 28, 2026

You haven't uploaded the generated source map to Sentry yet. Doing it this way makes running it locally and deploying it for testing quite difficult.

It published source map, Sentry be able to find the public one when have the error. I merged it and built v0.24.1, please try to deploy to canary to test

@dab246
Copy link
Copy Markdown
Member Author

dab246 commented Jan 28, 2026

You haven't uploaded the generated source map to Sentry yet. Doing it this way makes running it locally and deploying it for testing quite difficult.

It published source map, Sentry be able to find the public one when have the error. I merged it and built v0.24.1, please try to deploy to canary to test

How can I verify it on the Sentry dashboard?

@dab246
Copy link
Copy Markdown
Member Author

dab246 commented Jan 28, 2026

Okay, we can use a simpler method: publicizing the folder. So we will publicize the build/web folder containing the .js.map files so Sentry can find them automatically without having to upload them. Some things to note when using this method:

  • Versioning Conflicts: Deploying new code overwrites old source maps, breaking stack traces for users with cached app versions. Uploading maps to Sentry prevents this by locking specific maps to their exact release.
  • Network Reliability: Relying on Sentry to fetch large Flutter source maps (5–10 MB) is risky. Network lag or firewall blocks can prevent Sentry from downloading the files, causing debugging failures.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/gh-pages.yaml (1)

22-57: Limit SENTRY secrets scope to the build step.
Job-level env exposes secrets to all steps (including third‑party actions). Scoping them to the Build Flutter Web step reduces exposure.

🔒 Suggested change
-    env:
-      SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
-      SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
-      SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
...
       - name: Build Flutter Web
         uses: ./.github/actions/build-flutter-web
         env:
           FOLDER: ${{ github.event.pull_request.number }}
+          SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
+          SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
+          SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
🤖 Fix all issues with AI agents
In @.github/workflows/build-web-image.yaml:
- Around line 18-33: Add an explicit top-level permissions block to the workflow
to grant least-privilege token scopes: in the workflow YAML where the workflow
name and env are defined, add a permissions mapping that includes at minimum
"contents: read", "packages: write" and "artifact-metadata: write" (these cover
docker/login-action -> ghcr push and actions/upload-artifact). Place this
permissions block at the same level as "env" and "jobs" so the "build" job
inherits it.
- Around line 70-80: The Sentry release creation step using `npx `@sentry/cli`
releases new "$SENTRY_RELEASE"` is not idempotent and will fail on reruns if the
release already exists; update the workflow step that uses the SENTRY_RELEASE
env and `npx `@sentry/cli` releases new` to first check for the release (e.g.,
call `sentry-cli releases info "$SENTRY_RELEASE"`) and only create it when it
does not exist, ensuring the subsequent `releases files` and `releases finalize`
commands run regardless of prior runs.
🧹 Nitpick comments (1)
.github/actions/build-flutter-web/action.yml (1)

50-55: Harden version parsing against inline comments.
If pubspec.yaml ever includes version: 1.2.3 # comment, the current whitespace stripping would fold the comment into the version string. Stripping inline comments first keeps this robust.

♻️ Suggested tweak
-        VERSION=$(grep '^version:' pubspec.yaml | sed 's/version: //;s/[[:space:]]//g')
+        VERSION=$(grep '^version:' pubspec.yaml | sed -E 's/^version:[[:space:]]*//; s/[[:space:]]+#.*$//; s/[[:space:]]//g')

Comment on lines +70 to +80
# Upload source maps to Sentry via sentry-cli
- name: Upload source maps to Sentry
if: env.SENTRY_AUTH_TOKEN != ''
env:
SENTRY_RELEASE: ${{ steps.version.outputs.VERSION }}
run: |
npx @sentry/cli releases new "$SENTRY_RELEASE"
npx @sentry/cli releases files "$SENTRY_RELEASE" \
upload-sourcemaps ./source-maps/web/ \
--url-prefix '~/'
npx @sentry/cli releases finalize "$SENTRY_RELEASE"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

sentry-cli releases new idempotent duplicate release already exists

💡 Result:

sentry-cli releases new <VERSION> is not idempotent: if the release already exists, the command can fail with a “release already exists”/duplicate-type API error, and you need to handle that in your pipeline yourself. The most recent sentry-cli release (3.1.0, released Jan 12, 2026) does not mention adding an idempotent “create-if-missing” behavior for releases new in its notes/changelog. [1][2]

Practical ways to make it idempotent in CI

Option A (recommended): check first, then create

if ! sentry-cli releases info "$SENTRY_RELEASE" >/dev/null 2>&1; then
  sentry-cli releases new -p "$SENTRY_PROJECT" "$SENTRY_RELEASE"
fi

Option B: ignore the “already exists” failure

sentry-cli releases new -p "$SENTRY_PROJECT" "$SENTRY_RELEASE" || true

Sentry’s own CI examples still show a plain sentry-cli releases new ... as the “create release” step (which will fail if you rerun the same release without guarding it). [3]

Sources: [1] [2] [3]


🌐 Web query:

sentry-cli releases new --force flag documentation

💡 Result:

The current official Sentry CLI “Release Management” docs describe sentry-cli releases new (and mention --finalize), but do not document any --force flag for releases new. [1]

If your installed sentry-cli shows a --force option, the only official place you can reliably find its up-to-date meaning/behavior is the built-in CLI help:

sentry-cli releases new --help

Sentry’s CLI docs explicitly recommend using the help command to see documentation for all parameters. [2]

Sources: [1] [2]


Add idempotent release creation for Sentry reruns.

sentry-cli releases new fails if the release already exists, making this step non-idempotent. Reruns with the same version will fail. Guard the command by checking if the release exists first:

Suggested fix
sentry-cli releases info "$SENTRY_RELEASE" >/dev/null 2>&1 || \
  npx `@sentry/cli` releases new "$SENTRY_RELEASE"

Alternatively, suppress the error with || true, but checking existence first is safer.

🤖 Prompt for AI Agents
In @.github/workflows/build-web-image.yaml around lines 70 - 80, The Sentry
release creation step using `npx `@sentry/cli` releases new "$SENTRY_RELEASE"` is
not idempotent and will fail on reruns if the release already exists; update the
workflow step that uses the SENTRY_RELEASE env and `npx `@sentry/cli` releases
new` to first check for the release (e.g., call `sentry-cli releases info
"$SENTRY_RELEASE"`) and only create it when it does not exist, ensuring the
subsequent `releases files` and `releases finalize` commands run regardless of
prior runs.

@chibenwa
Copy link
Copy Markdown
Member

Is this work still needed if the source maps are directly onto the static assets?

If so, please set up a workshop with @Crash-- to arbitrate this.

@hoangdat
Copy link
Copy Markdown
Member

Yes, still need to upload source map, no way of Sentry can auto fetch public source map.

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@hoangdat
Copy link
Copy Markdown
Member

We tried to

  • build and extract source map from docker
  • upload to Sentry (which we use now) and github artifact

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In @.github/workflows/build-web-image.yaml:
- Around line 18-28: The workflow file contains duplicate top-level keys "name"
and "permissions" which is invalid YAML; remove the duplicate entries so there
is only one name key (keep "Build and push web Docker image") and a single
permissions block, merging permissions into that block (contents: read,
packages: write, actions: write, artifact-metadata: write) so no permission
lines are lost; update the file by deleting the redundant name/permissions
section and ensuring only the consolidated permissions block remains.
- Around line 1-17: The workflow is missing a on.workflow_call.secrets
declaration so callers cannot pass secrets referenced via ${{ secrets.* }}
(causing Sentry upload and DockerHub login to fail); add an
on.workflow_call.secrets block listing each secret name the workflow uses (e.g.,
the Sentry token and DockerHub credentials or any other secrets referenced),
using the existing on.workflow_call structure so callers can supply those
secrets when invoking the reusable workflow.

Comment on lines +1 to +17
on:
workflow_call:
inputs:
environment:
description: "Deployment environment (dev/prod)"
type: string
required: true
docker-tags:
description: "Docker metadata tags (passed to docker/metadata-action)"
type: string
required: true
artifact-name:
description: "Name for the source map artifact"
type: string
required: false
default: "source-maps"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

GitHub Actions reusable workflows secrets declaration workflow_call required

💡 Result:

To make a secret required for a reusable workflow, declare it under on.workflow_call.secrets in the called workflow and set required: true:

# .github/workflows/reusable.yml (called workflow)
on:
  workflow_call:
    secrets:
      personal_access_token:
        required: true

jobs:
  example:
    runs-on: ubuntu-latest
    steps:
      - run: echo "Got it"
        env:
          TOKEN: ${{ secrets.personal_access_token }}

Then, in the caller workflow, pass that secret using jobs.<job_id>.secrets (names must match the declaration), otherwise the call fails because it’s required:

# .github/workflows/caller.yml (caller workflow)
jobs:
  call:
    uses: org/repo/.github/workflows/reusable.yml@main
    secrets:
      personal_access_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}

Notes:

  • Passing a secret not declared in the called workflow causes an error. [2]
  • You can also pass all caller secrets with secrets: inherit. [1][2]

Sources: GitHub Docs on reusable workflows and workflow_call secrets. [1][2]


🏁 Script executed:

# First, let's check if this file exists and read its complete content
cd /tmp && git -C /tmp/repo rev-parse --show-toplevel 2>/dev/null || echo "Not in git repo"
# Read the complete workflow file to see all secrets references
cat .github/workflows/build-web-image.yaml

Repository: linagora/tmail-flutter

Length of output: 169


🏁 Script executed:

# Find the workflow file
fd -type f "build-web-image.yaml" 

# Also list files in .github/workflows directory if it exists
ls -la .github/workflows/ 2>/dev/null || echo "Directory not found"

Repository: linagora/tmail-flutter

Length of output: 892


🏁 Script executed:

# Read the complete workflow file
cat .github/workflows/build-web-image.yaml

Repository: linagora/tmail-flutter

Length of output: 4194


Declare reusable-workflow secrets in on.workflow_call.secrets so they can be properly passed by callers.

This workflow is a reusable workflow (workflow_call). Secrets used via ${{ secrets.* }} must be declared under on.workflow_call.secrets, otherwise callers cannot pass them and they resolve empty. This causes the Sentry upload and DockerHub login steps to fail.

🔐 Suggested `workflow_call.secrets` block
 on:
   workflow_call:
     inputs:
       environment:
         description: "Deployment environment (dev/prod)"
         type: string
         required: true
       docker-tags:
         description: "Docker metadata tags (passed to docker/metadata-action)"
         type: string
         required: true
       artifact-name:
         description: "Name for the source map artifact"
         type: string
         required: false
         default: "source-maps"
+    secrets:
+      SENTRY_AUTH_TOKEN:
+        required: false
+      SENTRY_ORG:
+        required: false
+      SENTRY_PROJECT:
+        required: false
+      DOCKERHUB_USERNAME:
+        required: true
+      DOCKERHUB_TOKEN:
+        required: true
🤖 Prompt for AI Agents
In @.github/workflows/build-web-image.yaml around lines 1 - 17, The workflow is
missing a on.workflow_call.secrets declaration so callers cannot pass secrets
referenced via ${{ secrets.* }} (causing Sentry upload and DockerHub login to
fail); add an on.workflow_call.secrets block listing each secret name the
workflow uses (e.g., the Sentry token and DockerHub credentials or any other
secrets referenced), using the existing on.workflow_call structure so callers
can supply those secrets when invoking the reusable workflow.

Comment on lines +18 to +28
name: Build and push web Docker image

permissions:
contents: read
name: Build and push web Docker image

permissions:
contents: read
packages: write
actions: write
artifact-metadata: write
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Remove duplicate name/permissions keys (invalid YAML).

Duplicate keys are invalid YAML and will fail linting; GitHub may reject the workflow file. Keep a single name and a single permissions block.

🧹 Suggested consolidation
-name: Build and push web Docker image
-
-permissions:
-  contents: read
-name: Build and push web Docker image
-
-permissions:
-  contents: read
-  packages: write
-  actions: write
-  artifact-metadata: write
+name: Build and push web Docker image
+
+permissions:
+  contents: read
+  packages: write
+  actions: write
+  artifact-metadata: write
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
name: Build and push web Docker image
permissions:
contents: read
name: Build and push web Docker image
permissions:
contents: read
packages: write
actions: write
artifact-metadata: write
name: Build and push web Docker image
permissions:
contents: read
packages: write
actions: write
artifact-metadata: write
🧰 Tools
🪛 actionlint (1.7.10)

22-22: key "name" is duplicated in "workflow" section. previously defined at line:18,col:1

(syntax-check)


24-24: key "permissions" is duplicated in "workflow" section. previously defined at line:20,col:1

(syntax-check)

🪛 YAMLlint (1.38.0)

[error] 22-22: duplication of key "name" in mapping

(key-duplicates)


[error] 24-24: duplication of key "permissions" in mapping

(key-duplicates)

🤖 Prompt for AI Agents
In @.github/workflows/build-web-image.yaml around lines 18 - 28, The workflow
file contains duplicate top-level keys "name" and "permissions" which is invalid
YAML; remove the duplicate entries so there is only one name key (keep "Build
and push web Docker image") and a single permissions block, merging permissions
into that block (contents: read, packages: write, actions: write,
artifact-metadata: write) so no permission lines are lost; update the file by
deleting the redundant name/permissions section and ensuring only the
consolidated permissions block remains.


- Minified JS in Sentry error reports is unreadable without source maps
- Source maps must not ship to production (exposes original code)
- Source maps must match the exact build deployed
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add "Sentry do not support using the website source maps but requires to upload it" potentially if possible with a ink justifying that choice on their end.

@chibenwa
Copy link
Copy Markdown
Member

Yes, still need to upload source map, no way of Sentry can auto fetch public source map.

Too bad :-( That's unfortunate.

Thanks for the clarification

However we then need a very clear documentation for a Twake Mail operator (think @dungphampt ) given XYZ twake mail flutter image, have VERY CLEAR instructions on how to upload the source maps onto Sentry. THis needs to be documented in the sentry documentation page and haveing the build artifact (the docker image/container) shall be sufficiant to conduct this task - no need to recompile. (Not just the ADR that is a good first step)

@Crash--
Copy link
Copy Markdown

Crash-- commented Jan 29, 2026

Yeah for sentry there is 2 mains reasons:

  • You can have http cache on main.js.map and so you can have a miss configuration between your app version & the source map. They want to be sure to have the right source with the right source map.
  • With this mechanism you are able to not deploy the source.map publicly. So you can still have a kind of obscuration

But yes, uploading source map to sentry adds complexity for the deploiement. That said, I agree the contract can be made clearer.

What do you do:

  • if the Sentry sourcemap upload fails? Do you fail to deploy?
  • what if we need to rollback a new deployed version (I don't know if we can do that even before this PR)? How do we use the right source map / version on Sentry?

(The "mental model" of sentry works better for mobile app. )

@hoangdat
Copy link
Copy Markdown
Member

hoangdat commented Feb 5, 2026

addressed in #4311

@hoangdat hoangdat closed this Feb 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants