diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 141349a..519969f 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -8,14 +8,14 @@ body: Thanks for taking the time to fill out this bug report! > [!WARNING] - > This repository only tracks installation scripts for our self-host project. For any other Bitwarden Server issues including Bitwarden Lite, please submit your report in [bitwarden/server](https://github.com/bitwarden/server) + > This repository only tracks installation scripts for our self-host project. For any other Bitwarden Server issues including Bitwarden lite, please submit your report in [bitwarden/server](https://github.com/bitwarden/server) Please do not submit feature requests. The [Community Forums](https://community.bitwarden.com) has a section for submitting, voting for, and discussing product feature requests. - type: checkboxes id: self-host-scripts attributes: label: Self-host installation scripts issue - description: "This repository only tracks installation scripts for our self-host project, any other Bitwarden Server issues including Bitwarden Lite should be reported in [bitwarden/server](https://github.com/bitwarden/server)" + description: "This repository only tracks installation scripts for our self-host project, any other Bitwarden Server issues including Bitwarden lite should be reported in [bitwarden/server](https://github.com/bitwarden/server)" options: - label: "I understand this repository only tracks self-host installation scripts and any other issues should be reported in bitwarden/server" required: true diff --git a/.github/workflows/build-bitwarden-lite.yml b/.github/workflows/build-bitwarden-lite.yml index f8088de..76b4391 100644 --- a/.github/workflows/build-bitwarden-lite.yml +++ b/.github/workflows/build-bitwarden-lite.yml @@ -1,4 +1,4 @@ -name: Build Bitwarden Lite +name: Build Bitwarden lite on: push: @@ -19,6 +19,10 @@ on: description: "Use the latest core version from version.json instead of branch" type: boolean default: false + use_latest_web_version: + description: "Use the latest web version from version.json instead of branch" + type: boolean + default: false pull_request: paths: - ".github/workflows/build-bitwarden-lite.yml" @@ -31,21 +35,20 @@ permissions: contents: read jobs: - build-docker: - name: Build Docker image + setup: + name: Setup runs-on: ubuntu-24.04 - permissions: - id-token: write - packages: write - security-events: write + outputs: + server_ref: ${{ steps.set-server-variables.outputs.server_ref }} + web_ref: ${{ steps.set-web-variables.outputs.web_ref }} steps: - name: Checkout Repository uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: persist-credentials: false - - name: Get server branch to checkout - id: server-branch-name + - name: Set Server variables + id: set-server-variables env: SERVER_BRANCH: ${{ inputs.server_branch }} USE_LATEST_CORE_VERSION: ${{ inputs.use_latest_core_version }} @@ -55,53 +58,49 @@ jobs: CORE_VERSION=$(jq -r '.versions.coreVersion' version.json) echo "Server version from version.json: $CORE_VERSION" echo "server_ref=refs/tags/v$CORE_VERSION" >> "$GITHUB_OUTPUT" - echo "ref_type=tag" >> "$GITHUB_OUTPUT" elif [[ -z "${SERVER_BRANCH}" ]]; then - echo "server_ref=main" >> "$GITHUB_OUTPUT" - echo "ref_type=branch" >> "$GITHUB_OUTPUT" + echo "server_ref=refs/heads/main" >> "$GITHUB_OUTPUT" else - echo "server_ref=${SERVER_BRANCH#refs/heads/}" >> "$GITHUB_OUTPUT" - echo "ref_type=branch" >> "$GITHUB_OUTPUT" + echo "server_ref=refs/heads/${SERVER_BRANCH#refs/heads/}" >> "$GITHUB_OUTPUT" fi - - name: Check Branch to Publish + - name: Set Web variables + id: set-web-variables env: - PUBLISH_BRANCHES: "main,rc,hotfix-rc" - SERVER_BRANCH: ${{ steps.server-branch-name.outputs.server_ref }} - REF_TYPE: ${{ steps.server-branch-name.outputs.ref_type }} - id: publish-branch-check + WEB_BRANCH: ${{ inputs.web_branch }} + USE_LATEST_WEB_VERSION: ${{ inputs.use_latest_web_version }} run: | - REF=${GITHUB_REF#refs/heads/} - - IFS="," read -a publish_branches <<< "$PUBLISH_BRANCHES" - - if [[ "${REF_TYPE}" == "tag" ]]; then - # If the build is triggered by a tag, always publish - echo "is_publish_branch=true" >> "$GITHUB_ENV" - elif [[ "${publish_branches[*]}" =~ "${REF}" && "${publish_branches[*]}" =~ "${SERVER_BRANCH}" ]]; then - echo "is_publish_branch=true" >> "$GITHUB_ENV" + if [[ "$USE_LATEST_WEB_VERSION" == "true" ]]; then + # Extract webVersion from version.json + WEB_VERSION=$(jq -r '.versions.webVersion' version.json) + echo "Web version from version.json: $WEB_VERSION" + echo "web_ref=refs/tags/web-v$WEB_VERSION" >> "$GITHUB_OUTPUT" + elif [[ -z "${WEB_BRANCH}" ]]; then + echo "web_ref=refs/heads/main" >> "$GITHUB_OUTPUT" else - echo "is_publish_branch=false" >> "$GITHUB_ENV" + echo "web_ref=refs/heads/${WEB_BRANCH#refs/heads/}" >> "$GITHUB_OUTPUT" fi - ########## Set up Docker ########## + build-docker: + name: Build Docker image + runs-on: ubuntu-24.04 + needs: setup + permissions: + id-token: write + packages: write + security-events: write + steps: + - name: Checkout Repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + - name: Set up QEMU emulators uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0 - name: Set up Docker Buildx uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - ########## Login to Docker registries ########## - - name: Log in to Azure - uses: bitwarden/gh-actions/azure-login@main - with: - subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - tenant_id: ${{ secrets.AZURE_TENANT_ID }} - client_id: ${{ secrets.AZURE_CLIENT_ID }} - - - name: Login to Azure ACR - run: az acr login -n bitwardenprod - - name: Login to GitHub Container Registry uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0 with: @@ -109,40 +108,33 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - ########## Generate image tag and build Docker image ########## - name: Generate Docker image tag id: tag env: - SERVER_BRANCH: ${{ steps.server-branch-name.outputs.server_ref }} - REF_TYPE: ${{ steps.server-branch-name.outputs.ref_type }} + SERVER_REF: ${{ needs.setup.outputs.server_ref }} run: | - if [[ "${REF_TYPE}" == "tag" ]]; then - # When using a tag (core version), always use beta tag - IMAGE_TAG=beta - echo "Using beta tag for core version release" + if [[ $SERVER_REF =~ ^refs/tags/v(.+)$ ]]; then + IMAGE_TAG="${BASH_REMATCH[1]}" else - # For branch-based builds, use the logic - IMAGE_TAG=$(echo "${SERVER_BRANCH}" | sed "s#/#-#g") # slash safe branch name - if [[ "${IMAGE_TAG}" == "main" ]]; then - IMAGE_TAG=dev - elif [[ ("${IMAGE_TAG}" == "rc") || ("${IMAGE_TAG}" == "hotfix-rc") ]]; then - IMAGE_TAG=beta - fi + IMAGE_TAG="${SERVER_REF#refs/heads/}" fi + if [[ "$IMAGE_TAG" == "main" ]]; then + IMAGE_TAG=dev + elif [[ ("$IMAGE_TAG" == "rc") || ("$IMAGE_TAG" == "hotfix-rc") ]]; then + # This if statement can be removed upon release so that 'rc' and 'hotfix-rc' tags are generated correctly. + IMAGE_TAG=beta + fi + + echo "Using $IMAGE_TAG for build" echo "image_tag=${IMAGE_TAG}" >> "$GITHUB_OUTPUT" - - name: Generate tag list - id: tag-list - env: - IMAGE_TAG: ${{ steps.tag.outputs.image_tag }} - IS_PUBLISH_BRANCH: ${{ env.is_publish_branch }} - run: | - if [[ ("${IMAGE_TAG}" == "dev" || "${IMAGE_TAG}" == "beta") && "${IS_PUBLISH_BRANCH}" == "true" ]]; then - echo "tags=$_AZ_REGISTRY/lite:${IMAGE_TAG},ghcr.io/bitwarden/lite:${IMAGE_TAG}" >> "$GITHUB_OUTPUT" - else - echo "tags=$_AZ_REGISTRY/lite:${IMAGE_TAG}" >> "$GITHUB_OUTPUT" - fi + - name: Log in to Azure + uses: bitwarden/gh-actions/azure-login@main + with: + subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + tenant_id: ${{ secrets.AZURE_TENANT_ID }} + client_id: ${{ secrets.AZURE_CLIENT_ID }} - name: Get Azure Key Vault secrets id: get-kv-secrets @@ -151,40 +143,45 @@ jobs: keyvault: gh-org-bitwarden secrets: "BW-GHAPP-ID,BW-GHAPP-KEY" + - name: Log out from Azure + uses: bitwarden/gh-actions/azure-logout@main + - name: Generate GH App token uses: actions/create-github-app-token@0f859bf9e69e887678d5bbfbee594437cb440ffe # v2.1.0 id: app-token with: app-id: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-ID }} private-key: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-KEY }} + permission-actions: read # for downloading workflow run artifacts + permission-contents: read # for checking out repos - name: Checkout server repo uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: repository: bitwarden/server token: ${{ steps.app-token.outputs.token }} - ref: ${{ steps.server-branch-name.outputs.server_ref }} + ref: ${{ needs.setup.outputs.server_ref }} path: "server" persist-credentials: false - name: Download web client branch artifacts for dev builds - if: steps.tag.outputs.image_tag == 'dev' + if: needs.setup.outputs.web_ref == 'refs/heads/main' uses: bitwarden/gh-actions/download-artifacts@main with: github_token: ${{ steps.app-token.outputs.token }} workflow: build-web.yml workflow_conclusion: success - branch: ${{ inputs.web_branch }} + branch: main repo: bitwarden/clients artifacts: "web-*-selfhosted-DEV.zip" - name: Set web artifact path for dev builds - if: steps.tag.outputs.image_tag == 'dev' + if: needs.setup.outputs.web_ref == 'refs/heads/main' id: set-web-artifact-path run: | WEB_ARTIFACT=$(find . -name "web-*-selfhosted-DEV.zip" | head -1) if [[ -n "${WEB_ARTIFACT}" ]]; then - echo "WEB_ARTIFACT_PATH=${WEB_ARTIFACT}" >> "$GITHUB_ENV" + echo "path=${WEB_ARTIFACT}" >> "$GITHUB_OUTPUT" fi - name: Build and push Docker image @@ -198,32 +195,24 @@ jobs: linux/arm/v7, linux/arm64/v8 push: true - tags: ${{ steps.tag-list.outputs.tags }} + tags: ghcr.io/bitwarden/lite:${{ steps.tag.outputs.image_tag }} build-args: | - WEB_ARTIFACT_PATH=${{ env.WEB_ARTIFACT_PATH }} + WEB_ARTIFACT_PATH=${{ steps.set-web-artifact-path.outputs.path }} - name: Install Cosign - if: env.is_publish_branch == 'true' uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0 - name: Sign image with Cosign - if: env.is_publish_branch == 'true' env: DIGEST: ${{ steps.build-docker.outputs.digest }} - TAGS: ${{ steps.tag-list.outputs.tags }} - run: | - IFS=',' read -r -a tags_array <<< "${TAGS}" - images=() - for tag in "${tags_array[@]}"; do - images+=("${tag}@${DIGEST}") - done - cosign sign --yes ${images[@]} + IMAGE_TAG: ghcr.io/bitwarden/lite:${{ steps.tag.outputs.image_tag }} + run: cosign sign --yes "${IMAGE_TAG}@${DIGEST}" - name: Scan Docker image id: container-scan uses: anchore/scan-action@f6601287cdb1efc985d6b765bbf99cb4c0ac29d8 # v7.0.0 with: - image: ${{ steps.tag-list.outputs.primary_tag }} + image: ghcr.io/bitwarden/lite:${{ steps.tag.outputs.image_tag }} fail-build: false output-format: sarif @@ -234,14 +223,8 @@ jobs: sha: ${{ contains(github.event_name, 'pull_request') && github.event.pull_request.head.sha || github.sha }} ref: ${{ contains(github.event_name, 'pull_request') && format('refs/pull/{0}/head', github.event.pull_request.number) || github.ref }} - - name: Log out of Docker - if: env.is_publish_branch == 'true' - run: | - docker logout ghcr.io - docker logout "$_AZ_REGISTRY" - - - name: Log out from Azure - uses: bitwarden/gh-actions/azure-logout@main + - name: Log out of GHCR + run: docker logout ghcr.io check-failures: @@ -254,10 +237,10 @@ jobs: steps: - name: Check if any job failed if: | - (github.ref == 'refs/heads/main' - || github.ref == 'refs/heads/rc' - || github.ref == 'refs/heads/hotfix-rc') - && contains(needs.*.result, 'failure') + (github.ref == 'refs/heads/main' || + github.ref == 'refs/heads/rc' || + github.ref == 'refs/heads/hotfix-rc') && + contains(needs.*.result, 'failure') run: exit 1 - name: Log in to Azure diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1461147..627a901 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,5 +1,5 @@ name: Release -run-name: Release ${{ inputs.release_type }} v${{ inputs.release_version }} +run-name: Release v${{ inputs.release_version }} on: workflow_dispatch: @@ -7,14 +7,6 @@ on: release_version: description: "Release Version (example: '2025.2.1')" required: true - release_type: - description: "Release Options" - required: true - default: "Release" - type: choice - options: - - Release - - Dry Run env: _AZ_REGISTRY: bitwardenprod.azurecr.io @@ -23,27 +15,13 @@ permissions: contents: read jobs: - setup: - name: Setup + self-host-version-check: + name: Check Self-Host Version Input + if: github.ref_name == 'main' runs-on: ubuntu-24.04 - permissions: - contents: read outputs: - _WEB_RELEASE_TAG: ${{ steps.set-tags.outputs.WEB_RELEASE_TAG }} - _CORE_RELEASE_TAG: ${{ steps.set-tags.outputs.CORE_RELEASE_TAG }} - _KEY_CONNECTOR_RELEASE_TAG: ${{ steps.set-tags.outputs.KEY_CONNECTOR_RELEASE_TAG }} - _LATEST_SELF_HOST_VERSION: ${{ steps.get-self-host.outputs.version }} + latest_version: ${{ steps.get-self-host.outputs.version }} steps: - - name: Branch check - if: ${{ inputs.release_type != 'Dry Run' }} - run: | - if [[ "$GITHUB_REF" != "refs/heads/main" ]]; then - echo "===================================" - echo "[!] Can only release from the 'main' branch" - echo "===================================" - exit 1 - fi - - name: Checkout repo uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: @@ -65,61 +43,181 @@ jobs: exit 1 fi - - name: Set Release Tags - id: set-tags - run: | - WEB=$(jq -r '.versions.webVersion' < version.json) - CORE=$(jq -r '.versions.coreVersion' < version.json) - KEY_CONNECTOR=$(jq -r '.versions.keyConnectorVersion' < version.json) - - { - echo "WEB_RELEASE_TAG=$WEB" - echo "CORE_RELEASE_TAG=$CORE" - echo "KEY_CONNECTOR_RELEASE_TAG=$KEY_CONNECTOR" - } >> "$GITHUB_OUTPUT" - release: - name: Create GitHub Release + update-versions: + name: "Update versions" runs-on: ubuntu-24.04 - needs: setup + needs: self-host-version-check permissions: contents: write + id-token: write + outputs: + core_release_tag: ${{ steps.update-core-version.outputs.tag }} + core_version_changed: ${{ steps.update-core-version.outputs.changed }} + web_release_tag: ${{ steps.update-web-version.outputs.tag }} + web_version_changed: ${{ steps.update-web-version.outputs.changed }} + key_connector_release_tag: ${{ steps.update-key-connector-version.outputs.tag }} + key_connector_version_changed: ${{ steps.update-key-connector-version.outputs.changed }} steps: - - name: Checkout repo + - name: Log in to Azure + uses: bitwarden/gh-actions/azure-login@main + with: + subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + tenant_id: ${{ secrets.AZURE_TENANT_ID }} + client_id: ${{ secrets.AZURE_CLIENT_ID }} + + - name: Get Azure Key Vault secrets + id: get-kv-secrets + uses: bitwarden/gh-actions/get-keyvault-secrets@main + with: + keyvault: gh-org-bitwarden + secrets: "BW-GHAPP-ID,BW-GHAPP-KEY" + + - name: Log out from Azure + uses: bitwarden/gh-actions/azure-logout@main + + - name: Generate GH App token + uses: actions/create-github-app-token@0f859bf9e69e887678d5bbfbee594437cb440ffe # v2.1.0 + id: app-token + with: + app-id: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-ID }} + private-key: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-KEY }} + permission-contents: write # for pushing commits + + - name: Checkout Branch uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: - fetch-depth: 0 - persist-credentials: false + ref: main + token: ${{ steps.app-token.outputs.token }} + persist-credentials: true + + - name: Get Latest Core Version + id: get-core + uses: bitwarden/gh-actions/get-release-version@main + with: + repository: bitwarden/server + trim: true + + - name: Update Core version + id: update-core-version + env: + NEW_VERSION: ${{ steps.get-core.outputs.version }} + run: | + OLD_VERSION=$(jq -r '.versions.coreVersion' version.json) + + sed -i -e "/^\s*COREVERSION\s*=\s*/s/[0-9]\+.[0-9]\+.[0-9]\+/$NEW_VERSION/" bitwarden.sh + sed -i -e "/^\s*\$coreVersion\s*=\s*/s/[0-9]\+.[0-9]\+.[0-9]\+/$NEW_VERSION/" bitwarden.ps1 + sed -i -e '/"coreVersion":/ s/"coreVersion":[^,]*/"coreVersion":"'$NEW_VERSION'"/' version.json + + if [[ "$OLD_VERSION" != "$NEW_VERSION" ]]; then + echo "Core version changed from '$OLD_VERSION' to '$NEW_VERSION'" >> "$GITHUB_STEP_SUMMARY" + echo "changed=true" >> "$GITHUB_OUTPUT" + fi + + echo "tag=$NEW_VERSION" >> "$GITHUB_OUTPUT" - - name: Get projects that changed versions - id: changed-projects + - name: Get Latest Web Version + id: get-web + uses: bitwarden/gh-actions/get-release-version@main + with: + repository: bitwarden/clients + monorepo: true + monorepo-project: web + trim: true + + - name: Update Web version + id: update-web-version env: - _LATEST_SELF_HOST_VERSION: ${{ needs.setup.outputs._LATEST_SELF_HOST_VERSION }} + NEW_VERSION: ${{ steps.get-web.outputs.version }} run: | - git diff --unified=0 "$_LATEST_SELF_HOST_VERSION" "$GITHUB_REF_NAME" -- version.json >> diff.txt + OLD_VERSION=$(jq -r '.versions.webVersion' version.json) - if grep -q "webVersion" diff.txt; then - echo "WEB_VERSION_CHANGED=true" >> "$GITHUB_OUTPUT" + sed -i -e "/^\s*WEBVERSION\s*=\s*/s/[0-9]\+.[0-9]\+.[0-9]\+/$NEW_VERSION/" bitwarden.sh + sed -i -e "/^\s*\$webVersion\s*=\s*/s/[0-9]\+.[0-9]\+.[0-9]\+/$NEW_VERSION/" bitwarden.ps1 + sed -i -e '/"webVersion":/ s/"webVersion":[^,]*/"webVersion":"'$NEW_VERSION'"/' version.json + + if [[ "$OLD_VERSION" != "$NEW_VERSION" ]]; then + echo "Web version changed from '$OLD_VERSION' to '$NEW_VERSION'" >> "$GITHUB_STEP_SUMMARY" + echo "changed=true" >> "$GITHUB_OUTPUT" fi - if grep -q "coreVersion" diff.txt; then - echo "CORE_VERSION_CHANGED=true" >> "$GITHUB_OUTPUT" + echo "tag=$NEW_VERSION" >> "$GITHUB_OUTPUT" + + - name: Get Latest Key Connector Version + id: get-key-connector + uses: bitwarden/gh-actions/get-release-version@main + with: + repository: bitwarden/key-connector + trim: true + + - name: Update Key Connector version + id: update-key-connector-version + env: + NEW_VERSION: ${{ steps.get-key-connector.outputs.version }} + run: | + OLD_VERSION=$(jq -r '.versions.keyConnectorVersion' version.json) + + sed -i -e "/^\s*KEYCONNECTORVERSION\s*=\s*/s/[0-9]\+.[0-9]\+.[0-9]\+/$NEW_VERSION/" bitwarden.sh + sed -i -e "/^\s*\$keyConnectorVersion\s*=\s*/s/[0-9]\+.[0-9]\+.[0-9]\+/$NEW_VERSION/" bitwarden.ps1 + sed -i -e '/"keyConnectorVersion":/ s/"keyConnectorVersion":[^,]*/"keyConnectorVersion":"'$NEW_VERSION'"/' version.json + + if [[ "$OLD_VERSION" != "$NEW_VERSION" ]]; then + echo "Key Connector version changed from '$OLD_VERSION' to '$NEW_VERSION'" >> "$GITHUB_STEP_SUMMARY" + echo "changed=true" >> "$GITHUB_OUTPUT" fi - if grep -q "keyConnectorVersion" diff.txt; then - echo "KEY_CONNECTOR_VERSION_CHANGED=true" >> "$GITHUB_OUTPUT" + echo "tag=$NEW_VERSION" >> "$GITHUB_OUTPUT" + + - name: Check if version changed + id: version-changed + run: | + if [ -n "$(git status --porcelain)" ]; then + echo "changes_to_commit=true" >> "$GITHUB_OUTPUT" + else + echo "changes_to_commit=FALSE" >> "$GITHUB_OUTPUT" + echo "No changes to commit!"; fi + - name: Configure Git + if: ${{ steps.version-changed.outputs.changes_to_commit == 'true' }} + run: | + git config --local user.email "178206702+bw-ghapp[bot]@users.noreply.github.com" + git config --local user.name "bw-ghapp[bot]" + + - name: Commit files + if: ${{ steps.version-changed.outputs.changes_to_commit == 'true' }} + run: git commit -m "Updated core, web, and key-connector versions" -a + + - name: Push changes + if: ${{ steps.version-changed.outputs.changes_to_commit == 'true' }} + run: git push + + + release-github: + name: Create GitHub Release + runs-on: ubuntu-24.04 + needs: + - self-host-version-check + - update-versions + permissions: + contents: write + steps: + - name: Checkout repo + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + fetch-depth: 0 + persist-credentials: false + ref: main + - name: Prepare release notes id: prepare-release-notes env: - CORE_VERSION_CHANGED: ${{ steps.changed-projects.outputs.CORE_VERSION_CHANGED }} - CORE_RELEASE_TAG: ${{ needs.setup.outputs._CORE_RELEASE_TAG }} - WEB_VERSION_CHANGED: ${{ steps.changed-projects.outputs.WEB_VERSION_CHANGED }} - WEB_RELEASE_TAG: ${{ needs.setup.outputs._WEB_RELEASE_TAG }} - KEY_CONNECTOR_VERSION_CHANGED: ${{ steps.changed-projects.outputs.KEY_CONNECTOR_VERSION_CHANGED }} - KEY_CONNECTOR_RELEASE_TAG: ${{ needs.setup.outputs._KEY_CONNECTOR_RELEASE_TAG }} - + CORE_RELEASE_TAG: ${{ needs.update-versions.outputs.core_release_tag }} + CORE_VERSION_CHANGED: ${{ needs.update-versions.outputs.core_version_changed }} + WEB_RELEASE_TAG: ${{ needs.update-versions.outputs.web_release_tag }} + WEB_VERSION_CHANGED: ${{ needs.update-versions.outputs.web_version_changed }} + KEY_CONNECTOR_RELEASE_TAG: ${{ needs.update-versions.outputs.key_connector_release_tag }} + KEY_CONNECTOR_VERSION_CHANGED: ${{ needs.update-versions.outputs.key_connector_version_changed }} run: | RELEASE_NOTES="" @@ -147,8 +245,7 @@ jobs: echo EOF ) >> "$GITHUB_OUTPUT" - - name: Create release - if: ${{ inputs.release_type != 'Dry Run' }} + - name: Create GitHub release uses: ncipollo/release-action@bcfe5470707e8832e12347755757cec0eb3c22af # v1.18.0 with: artifacts: 'bitwarden.sh, @@ -156,7 +253,6 @@ jobs: bitwarden.ps1, run.ps1, version.json' - commit: ${{ github.sha }} tag: "v${{ inputs.release_version }}" name: "Version ${{ inputs.release_version }}" body: ${{ steps.prepare-release-notes.outputs.RELEASE_NOTES }} @@ -167,9 +263,7 @@ jobs: release-s3: name: Upload version.json runs-on: ubuntu-24.04 - needs: - - setup - - release + needs: release-github permissions: contents: read id-token: write @@ -177,8 +271,8 @@ jobs: - name: Checkout repo uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: - ref: main persist-credentials: false + ref: main - name: Log in to Azure uses: bitwarden/gh-actions/azure-login@main @@ -200,7 +294,6 @@ jobs: uses: bitwarden/gh-actions/azure-logout@main - name: Upload version.json to S3 bucket - if: ${{ inputs.release_type != 'Dry Run' }} env: AWS_ACCESS_KEY_ID: ${{ steps.retrieve-secrets.outputs.aws-selfhost-version-access-id }} AWS_SECRET_ACCESS_KEY: ${{ steps.retrieve-secrets.outputs.aws-selfhost-version-access-key }} @@ -216,16 +309,13 @@ jobs: name: Tag and push ${{ matrix.project_name }} image with release version and latest runs-on: ubuntu-24.04 needs: - - setup - - release - env: - _CORE_RELEASE_TAG: ${{ needs.setup.outputs._CORE_RELEASE_TAG }} - _BRANCH_NAME: main + - update-versions + - release-github permissions: id-token: write packages: write strategy: - fail-fast: false + fail-fast: true matrix: include: - project_name: Admin @@ -243,12 +333,10 @@ jobs: - project_name: Setup - project_name: Sso - project_name: Web - release_tag: ${{ needs.setup.outputs._WEB_RELEASE_TAG }} steps: - name: Checkout repo uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: - ref: main persist-credentials: false - name: Install Cosign @@ -262,20 +350,20 @@ jobs: client_id: ${{ secrets.AZURE_CLIENT_ID }} - name: Setup project name and release tag - id: setup + id: image-setup env: - MATRIX_RELEASE_TAG: ${{ matrix.release_tag }} + CORE_RELEASE_TAG: ${{ needs.update-versions.outputs.core_release_tag }} + WEB_RELEASE_TAG: ${{ needs.update-versions.outputs.web_release_tag }} run: | PROJECT_NAME=$(echo "${{ matrix.project_name }}" | awk '{print tolower($0)}') echo "Matrix name: ${{ matrix.project_name }}" echo "PROJECT_NAME: $PROJECT_NAME" - echo "_PROJECT_NAME=$PROJECT_NAME" >> "$GITHUB_ENV" + echo "project_name=$PROJECT_NAME" >> "$GITHUB_OUTPUT" - if [ -z "${MATRIX_RELEASE_TAG}" ]; then - # Use core release tag by default. - echo "_RELEASE_TAG=$_CORE_RELEASE_TAG" >> "$GITHUB_ENV" + if [[ "$PROJECT_NAME" == "web" ]]; then + echo "release_tag=$WEB_RELEASE_TAG" >> "$GITHUB_OUTPUT" else - echo "_RELEASE_TAG=${MATRIX_RELEASE_TAG}" >> "$GITHUB_ENV" + echo "release_tag=$CORE_RELEASE_TAG" >> "$GITHUB_OUTPUT" fi ### ghcr.io section @@ -287,17 +375,22 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Push version and latest image - if: ${{ inputs.release_type != 'Dry Run' }} + env: + PROJECT_NAME: ${{ steps.image-setup.outputs.project_name }} + RELEASE_TAG: ${{ steps.image-setup.outputs.release_tag }} run: | skopeo --version skopeo login "$_AZ_REGISTRY" -u 00000000-0000-0000-0000-000000000000 -p "$(az acr login --expose-token --name "${_AZ_REGISTRY%.azurecr.io}" | jq -r .accessToken)" - skopeo copy --all "docker://$_AZ_REGISTRY/$_PROJECT_NAME:$_RELEASE_TAG" "docker://ghcr.io/bitwarden/$_PROJECT_NAME:$_RELEASE_TAG" - skopeo copy --all "docker://$_AZ_REGISTRY/$_PROJECT_NAME:latest" "docker://ghcr.io/bitwarden/$_PROJECT_NAME:latest" + skopeo copy --all "docker://$_AZ_REGISTRY/$PROJECT_NAME:$RELEASE_TAG" "docker://ghcr.io/bitwarden/$PROJECT_NAME:$RELEASE_TAG" + skopeo copy --all "docker://$_AZ_REGISTRY/$PROJECT_NAME:latest" "docker://ghcr.io/bitwarden/$PROJECT_NAME:latest" - name: Sign image with Cosign + env: + PROJECT_NAME: ${{ steps.image-setup.outputs.project_name }} + RELEASE_TAG: ${{ steps.image-setup.outputs.release_tag }} run: | - cosign sign --yes "ghcr.io/bitwarden/$_PROJECT_NAME:$_RELEASE_TAG" - cosign sign --yes "ghcr.io/bitwarden/$_PROJECT_NAME:latest" + cosign sign --yes "ghcr.io/bitwarden/$PROJECT_NAME:$RELEASE_TAG" + cosign sign --yes "ghcr.io/bitwarden/$PROJECT_NAME:latest" - name: Log out of Docker run: | @@ -309,11 +402,9 @@ jobs: release-bitwarden-lite: - name: Release Bitwarden Lite + name: Release Bitwarden lite runs-on: ubuntu-24.04 - needs: - - setup - - release + needs: update-versions env: _RELEASE_VERSION: ${{ inputs.release_version }}-beta # TODO: remove `-beta` after GA permissions: @@ -338,7 +429,6 @@ jobs: uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0 - name: Push version and latest image - if: ${{ inputs.release_type != 'Dry Run' }} run: | skopeo --version skopeo login "$_AZ_REGISTRY" -u 00000000-0000-0000-0000-000000000000 -p "$(az acr login --expose-token --name "${_AZ_REGISTRY%.azurecr.io}" | jq -r .accessToken)" @@ -361,24 +451,14 @@ jobs: run: az acr login -n "${_AZ_REGISTRY%.azurecr.io}" - name: Pull latest project image - run: | - if [[ "${{ inputs.release_type }}" == "Dry Run" ]]; then - docker pull "$_AZ_REGISTRY/lite:dev" - else - docker pull "$_AZ_REGISTRY/lite:beta" - fi + run: docker pull "$_AZ_REGISTRY/lite:beta" - name: Tag version and latest run: | - if [[ "${{ inputs.release_type }}" == "Dry Run" ]]; then - docker tag "$_AZ_REGISTRY/lite:dev" "$_AZ_REGISTRY/lite:dryrun" - else - docker tag "$_AZ_REGISTRY/lite:beta" "$_AZ_REGISTRY/lite:$_RELEASE_VERSION" - docker tag "$_AZ_REGISTRY/lite:beta" "$_AZ_REGISTRY/lite:latest" - fi + docker tag "$_AZ_REGISTRY/lite:beta" "$_AZ_REGISTRY/lite:$_RELEASE_VERSION" + docker tag "$_AZ_REGISTRY/lite:beta" "$_AZ_REGISTRY/lite:latest" - name: Push version and latest image - if: ${{ inputs.release_type != 'Dry Run' }} run: | docker push "$_AZ_REGISTRY/lite:$_RELEASE_VERSION" docker push "$_AZ_REGISTRY/lite:latest" @@ -394,8 +474,6 @@ jobs: name: Trigger workflows runs-on: ubuntu-24.04 needs: - - setup - - release - tag-push-latest-images - release-bitwarden-lite permissions: @@ -424,6 +502,7 @@ jobs: with: app-id: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-ID }} private-key: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-KEY }} + permission-actions: write - name: Trigger release-digital-ocean workflow uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 diff --git a/.github/workflows/update-versions.yml b/.github/workflows/update-versions.yml deleted file mode 100644 index 96d250f..0000000 --- a/.github/workflows/update-versions.yml +++ /dev/null @@ -1,186 +0,0 @@ -name: Update Versions - -on: - workflow_dispatch: - -permissions: {} - -jobs: - setup: - name: Setup - if: github.ref_name == 'main' - runs-on: ubuntu-24.04 - permissions: - contents: read - outputs: - core_version: ${{ steps.get-core.outputs.version }} - core_version_update: ${{ steps.core-update.outputs.update }} - web_version: ${{ steps.get-web.outputs.version }} - web_version_update: ${{ steps.web-update.outputs.update }} - key_connector_version: ${{ steps.get-key-connector.outputs.version }} - key_connector_version_update: ${{ steps.key-connector-update.outputs.update }} - steps: - - name: Checkout Branch - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - with: - persist-credentials: false - - - name: Get Latest Core Version - id: get-core - uses: bitwarden/gh-actions/get-release-version@main - with: - repository: bitwarden/server - trim: true - - - name: Check if Core Version needs updating - id: core-update - env: - LATEST_CORE_VERSION: ${{ steps.get-core.outputs.version }} - run: | - CORE_VERSION=$(sed -r -n "s/COREVERSION=\"([0-9]+\.[0-9]+\.[0-9]+)\"/\1/p" bitwarden.sh) - echo "Core Version: $CORE_VERSION" - echo "Latest Core Version: $LATEST_CORE_VERSION" - if [ "$CORE_VERSION" != "$LATEST_CORE_VERSION" ]; then - echo "Needs Core update!" - echo "update=1" >> "$GITHUB_OUTPUT" - else - echo "update=0" >> "$GITHUB_OUTPUT" - fi - - - name: Get Latest Web Version - id: get-web - uses: bitwarden/gh-actions/get-release-version@main - with: - repository: bitwarden/clients - monorepo: true - monorepo-project: web - trim: true - - - name: Check if Web Version needs updating - id: web-update - env: - LATEST_WEB_VERSION: ${{ steps.get-web.outputs.version }} - run: | - WEB_VERSION=$(sed -r -n "s/WEBVERSION=\"([0-9]+\.[0-9]+\.[0-9]+)\"/\1/p" bitwarden.sh) - echo "Web Version: $WEB_VERSION" - echo "Latest Web Version: $LATEST_WEB_VERSION" - if [ "$WEB_VERSION" != "$LATEST_WEB_VERSION" ]; then - echo "Needs Web update!" - echo "update=1" >> "$GITHUB_OUTPUT" - else - echo "update=0" >> "$GITHUB_OUTPUT" - fi - - - name: Get Latest Key Connector Version - id: get-key-connector - uses: bitwarden/gh-actions/get-release-version@main - with: - repository: bitwarden/key-connector - trim: true - - - name: Check if Key Connector Version needs updating - id: key-connector-update - env: - LATEST_KEY_CONNECTOR_VERSION: ${{ steps.get-key-connector.outputs.version }} - run: | - KEY_CONNECTOR_VERSION=$(sed -r -n "s/KEYCONNECTORVERSION=\"([0-9]+\.[0-9]+\.[0-9]+)\"/\1/p" bitwarden.sh) - echo "Key Connector Version: $KEY_CONNECTOR_VERSION" - echo "Latest Key Connector Version: $LATEST_KEY_CONNECTOR_VERSION" - if [ "$KEY_CONNECTOR_VERSION" != "$LATEST_KEY_CONNECTOR_VERSION" ]; then - echo "Needs Key Connector update!" - echo "update=1" >> "$GITHUB_OUTPUT" - else - echo "update=0" >> "$GITHUB_OUTPUT" - fi - - - update-versions: - name: "Update versions" - if: | - needs.setup.outputs.core_version_update == 1 || - needs.setup.outputs.web_version_update == 1 || - needs.setup.outputs.key_connector_version_update == 1 - runs-on: ubuntu-24.04 - needs: setup - permissions: - id-token: write - steps: - - name: Log in to Azure - uses: bitwarden/gh-actions/azure-login@main - with: - subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - tenant_id: ${{ secrets.AZURE_TENANT_ID }} - client_id: ${{ secrets.AZURE_CLIENT_ID }} - - - name: Get Azure Key Vault secrets - id: get-kv-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@main - with: - keyvault: gh-org-bitwarden - secrets: "BW-GHAPP-ID,BW-GHAPP-KEY" - - - name: Log out from Azure - uses: bitwarden/gh-actions/azure-logout@main - - - name: Generate GH App token - uses: actions/create-github-app-token@0f859bf9e69e887678d5bbfbee594437cb440ffe # v2.1.0 - id: app-token - with: - app-id: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-ID }} - private-key: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-KEY }} - permission-contents: write - - - - name: Checkout Branch - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - with: - ref: main - token: ${{ steps.app-token.outputs.token }} - persist-credentials: true - - - name: Configure Git - run: | - git config --local user.email "actions@github.com" - git config --local user.name "Github Actions" - - - name: Update Core Version - env: - VERSION: ${{ needs.setup.outputs.core_version }} - run: | - sed -i -e "/^\s*COREVERSION\s*=\s*/s/[0-9]\+.[0-9]\+.[0-9]\+/$VERSION/" bitwarden.sh - sed -i -e "/^\s*\$coreVersion\s*=\s*/s/[0-9]\+.[0-9]\+.[0-9]\+/$VERSION/" bitwarden.ps1 - sed -i -e '/"coreVersion":/ s/"coreVersion":[^,]*/"coreVersion":"'$VERSION'"/' version.json - - - name: Update Web Version - env: - VERSION: ${{ needs.setup.outputs.web_version }} - run: | - sed -i -e "/^\s*WEBVERSION\s*=\s*/s/[0-9]\+.[0-9]\+.[0-9]\+/$VERSION/" bitwarden.sh - sed -i -e "/^\s*\$webVersion\s*=\s*/s/[0-9]\+.[0-9]\+.[0-9]\+/$VERSION/" bitwarden.ps1 - sed -i -e '/"webVersion":/ s/"webVersion":[^,]*/"webVersion":"'$VERSION'"/' version.json - - - name: Update Key Connector Version - env: - VERSION: ${{ needs.setup.outputs.key_connector_version }} - run: | - sed -i -e "/^\s*KEYCONNECTORVERSION\s*=\s*/s/[0-9]\+.[0-9]\+.[0-9]\+/$VERSION/" bitwarden.sh - sed -i -e "/^\s*\$keyConnectorVersion\s*=\s*/s/[0-9]\+.[0-9]\+.[0-9]\+/$VERSION/" bitwarden.ps1 - sed -i -e '/"keyConnectorVersion":/ s/"keyConnectorVersion":[^,]*/"keyConnectorVersion":"'$VERSION'"/' version.json - - - name: Check if version changed - id: version-changed - run: | - if [ -n "$(git status --porcelain)" ]; then - echo "changes_to_commit=TRUE" >> "$GITHUB_OUTPUT" - else - echo "changes_to_commit=FALSE" >> "$GITHUB_OUTPUT" - echo "No changes to commit!"; - fi - - - name: Commit files - if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }} - run: git commit -m "Updated core, web, and key-connector versions" -a - - - name: Push changes - if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }} - run: git push diff --git a/bitwarden-lite/Dockerfile b/bitwarden-lite/Dockerfile index b4e7cd0..045b04c 100644 --- a/bitwarden-lite/Dockerfile +++ b/bitwarden-lite/Dockerfile @@ -16,12 +16,14 @@ WORKDIR /tmp # Grab last tag/release of the 'web' client RUN if [ -z "${WEB_ARTIFACT_PATH}" ]; then \ - git ls-remote --tags https://github.com/bitwarden/clients.git | grep refs/tags/web | cut -d/ -f3 | sort -Vr | head -1 > tag.txt; \ + git ls-remote --tags https://github.com/bitwarden/clients.git \ + | grep -E 'refs/tags/web-v[0-9]{4}\.([1-9]|1[0-2])\.[0-9]+' \ + | cut -d/ -f3 | sort -Vr | head -1 > tag.txt; \ fi # Extract the version of the 'web' client RUN if [ -z "${WEB_ARTIFACT_PATH}" ]; then \ - cat tag.txt | grep -o -E "[0-9]{4}\.[0-9]{1,2}\.[0-9]+" > version.txt; \ + cat tag.txt | grep -o -E '[0-9]{4}\.([1-9]|1[0-2])\.[0-9]+' > version.txt; \ fi # Download the built release artifact for the 'web' client