Add UI copy and German translation style guides #15162
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Docker | |
| on: | |
| workflow_dispatch: {} | |
| push: | |
| tags: [v*] | |
| pull_request: {} | |
| schedule: | |
| # This job can take a while, and we have usage limits, so just publish develop only twice a day | |
| - cron: "0 7/12 * * *" | |
| concurrency: ${{ github.workflow }}-${{ github.ref_name }} | |
| permissions: {} | |
| jobs: | |
| buildx: | |
| name: Docker Buildx | |
| runs-on: ubuntu-24.04 | |
| environment: ${{ github.event_name != 'pull_request' && 'dockerhub' || '' }} | |
| permissions: | |
| id-token: write # needed for signing the images with GitHub OIDC Token | |
| packages: write # needed for publishing packages to GHCR | |
| env: | |
| TEST_TAG: ghcr.io/element-hq/element-web:test | |
| TEST_TAG_MODULES: ghcr.io/element-hq/element-web/modules:test | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| fetch-depth: 0 # needed for docker-package to be able to calculate the version | |
| persist-credentials: false | |
| - name: Install Cosign | |
| uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2 | |
| if: github.event_name != 'pull_request' | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4 | |
| with: | |
| install: true | |
| - name: Build and load | |
| uses: docker/bake-action@d3418bd7d0e9324001bca92fa8ba175ea7e6dc9b # v7 | |
| with: | |
| source: . | |
| files: ./docker-bake.hcl | |
| load: true | |
| set: | | |
| element-web.tags=${{ env.TEST_TAG }} | |
| element-web-modules.tags=${{ env.TEST_TAG_MODULES }} | |
| - name: Test the image | |
| env: | |
| IMAGE: ${{ env.TEST_TAG }} | |
| timeout-minutes: 2 | |
| run: | | |
| set -x | |
| # Make a fake module to test the image | |
| MODULE_PATH="module_name/index.js" | |
| mkdir -p $(dirname test_modules/$MODULE_PATH) | |
| echo 'alert("Testing");' > test_modules/$MODULE_PATH | |
| # Spin up a container of the image | |
| ELEMENT_WEB_PORT=8181 | |
| CONTAINER_ID=$( | |
| docker run \ | |
| --rm \ | |
| -e "ELEMENT_WEB_PORT=$ELEMENT_WEB_PORT" \ | |
| -dp "$ELEMENT_WEB_PORT:$ELEMENT_WEB_PORT" \ | |
| -v $(pwd)/test_modules:/modules \ | |
| "$IMAGE" \ | |
| ) | |
| # Run some smoke tests | |
| wget --retry-connrefused --tries=5 -q --wait=3 --spider "http://localhost:$ELEMENT_WEB_PORT/modules/module_name/index.js" | |
| MODULE_0=$(curl "http://localhost:$ELEMENT_WEB_PORT/config.json" | jq -r .modules[0]) | |
| test "$MODULE_0" = "/modules/${MODULE_PATH}" | |
| # Check healthcheck | |
| until test "$(docker inspect -f {{.State.Health.Status}} $CONTAINER_ID)" == "healthy"; do | |
| sleep 1 | |
| done | |
| # Clean up | |
| docker stop "$CONTAINER_ID" | |
| - name: Test the modules image | |
| env: | |
| IMAGE: ${{ env.TEST_TAG_MODULES }} | |
| timeout-minutes: 2 | |
| run: | | |
| set -x | |
| ELEMENT_WEB_PORT=8182 | |
| CONTAINER_ID=$( | |
| docker run \ | |
| --rm \ | |
| -e "ELEMENT_WEB_PORT=$ELEMENT_WEB_PORT" \ | |
| -dp "$ELEMENT_WEB_PORT:$ELEMENT_WEB_PORT" \ | |
| "$IMAGE" \ | |
| ) | |
| # Every module pinned in the Dockerfile should be listed in the config and served | |
| MODULES=$(grep -oE '^ARG MODULE_[A-Z0-9_]+_VERSION=' apps/web/Dockerfile | | |
| sed -E 's/^ARG MODULE_(.*)_VERSION=$/\1/' | tr '[:upper:]_' '[:lower:]-') | |
| test -n "$MODULES" | |
| CONFIG=$(wget --retry-connrefused --tries=5 -q --wait=3 -O - "http://localhost:$ELEMENT_WEB_PORT/config.json") | |
| for MODULE in $MODULES; do | |
| echo "$CONFIG" | jq -e --arg m "/modules/$MODULE/index.js" '.modules | index($m)' | |
| wget -q --spider "http://localhost:$ELEMENT_WEB_PORT/modules/$MODULE/index.js" | |
| done | |
| # Check healthcheck | |
| until test "$(docker inspect -f '{{.State.Health.Status}}' "$CONTAINER_ID")" == "healthy"; do | |
| sleep 1 | |
| done | |
| # Clean up | |
| docker stop "$CONTAINER_ID" | |
| - name: Docker meta | |
| id: meta | |
| uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6 | |
| if: github.event_name != 'pull_request' | |
| with: | |
| images: | | |
| vectorim/element-web | |
| ghcr.io/element-hq/element-web | |
| oci-push.vpn.infra.element.io/element-web | |
| tags: | | |
| type=ref,event=branch | |
| type=ref,event=tag | |
| flavor: | | |
| latest=${{ contains(github.ref_name, '-rc.') && 'false' || 'auto' }} | |
| bake-target: docker-metadata-action | |
| - name: Docker meta (modules) | |
| id: meta-modules | |
| uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6 | |
| if: github.event_name != 'pull_request' | |
| with: | |
| images: ghcr.io/element-hq/element-web/modules | |
| tags: | | |
| type=ref,event=branch | |
| type=ref,event=tag | |
| flavor: | | |
| latest=${{ contains(github.ref_name, '-rc.') && 'false' || 'auto' }} | |
| bake-target: docker-metadata-action-modules | |
| - name: Login to Docker Hub | |
| uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4 | |
| if: github.event_name != 'pull_request' | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| - name: Login to GitHub Container Registry | |
| uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4 | |
| if: github.event_name != 'pull_request' | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.repository_owner }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Connect to Tailscale | |
| uses: tailscale/github-action@306e68a486fd2350f2bfc3b19fcd143891a4a2d8 # v4 | |
| if: github.event_name != 'pull_request' | |
| with: | |
| oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }} | |
| audience: ${{ secrets.TS_AUDIENCE }} | |
| tags: tag:github-actions | |
| - name: Compute vault jwt role name | |
| id: vault-jwt-role | |
| if: github.event_name != 'pull_request' | |
| run: | | |
| echo "role_name=github_service_management_$( echo "${{ github.repository }}" | sed -r 's|[/-]|_|g')" | tee -a "$GITHUB_OUTPUT" | |
| - name: Get team registry token | |
| id: import-secrets | |
| uses: hashicorp/vault-action@892a26828f195e65540a40b4768ae4571f51ebfc # v4 | |
| if: github.event_name != 'pull_request' | |
| with: | |
| url: https://vault.infra.ci.i.element.dev | |
| role: ${{ steps.vault-jwt-role.outputs.role_name }} | |
| path: service-management/github-actions | |
| jwtGithubAudience: https://vault.infra.ci.i.element.dev | |
| method: jwt | |
| secrets: | | |
| services/web-repositories/secret/data/oci.element.io username | OCI_USERNAME ; | |
| services/web-repositories/secret/data/oci.element.io password | OCI_PASSWORD ; | |
| - name: Login to oci.element.io Registry | |
| uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4 | |
| if: github.event_name != 'pull_request' | |
| with: | |
| registry: oci-push.vpn.infra.element.io | |
| username: ${{ steps.import-secrets.outputs.OCI_USERNAME }} | |
| password: ${{ steps.import-secrets.outputs.OCI_PASSWORD }} | |
| # Both targets are built in a single bake so that the app is only compiled once. | |
| - name: Build and push | |
| id: build-and-push | |
| uses: docker/bake-action@d3418bd7d0e9324001bca92fa8ba175ea7e6dc9b # v7 | |
| if: github.event_name != 'pull_request' | |
| with: | |
| source: . | |
| files: | | |
| ./docker-bake.hcl | |
| ${{ steps.meta.outputs.bake-file }} | |
| ${{ steps.meta-modules.outputs.bake-file }} | |
| push: true | |
| vars: | | |
| PLATFORMS=linux/amd64,linux/arm64 | |
| - name: Sign the images with GitHub OIDC Token | |
| env: | |
| METADATA: ${{ steps.build-and-push.outputs.metadata }} | |
| TAGS: ${{ steps.meta.outputs.tags }} | |
| TAGS_MODULES: ${{ steps.meta-modules.outputs.tags }} | |
| if: github.event_name != 'pull_request' | |
| run: | | |
| images="" | |
| sign_target() { | |
| digest=$(echo "$METADATA" | jq -er --arg t "$1" '.[$t]."containerimage.digest"') | |
| for tag in $2; do | |
| images+="${tag}@${digest} " | |
| done | |
| } | |
| sign_target element-web "$TAGS" | |
| sign_target element-web-modules "$TAGS_MODULES" | |
| cosign sign --yes ${images} | |
| - name: Update repo description | |
| uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5 | |
| if: github.event_name != 'pull_request' | |
| continue-on-error: true | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| repository: vectorim/element-web |