From 76b443cf99259fa7a267a40d27681c3fc757b93b Mon Sep 17 00:00:00 2001 From: fntyler <71953103+fntyler@users.noreply.github.com> Date: Fri, 1 May 2026 15:02:24 -0400 Subject: [PATCH] BRE-1869 Delete release workflows [BRE-1869](https://bitwarden.atlassian.net/browse/BRE-1869) Remove release workflows from self-host repository. --- .github/workflows/release-aws.yml | 181 ------- .github/workflows/release-azure.yml | 179 ------- .github/workflows/release-digital-ocean.yml | 166 ------ .github/workflows/release.yml | 541 -------------------- 4 files changed, 1067 deletions(-) delete mode 100644 .github/workflows/release-aws.yml delete mode 100644 .github/workflows/release-azure.yml delete mode 100644 .github/workflows/release-digital-ocean.yml delete mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release-aws.yml b/.github/workflows/release-aws.yml deleted file mode 100644 index 9e35978f..00000000 --- a/.github/workflows/release-aws.yml +++ /dev/null @@ -1,181 +0,0 @@ -name: Release AWS Marketplace - -on: - push: - paths: - - "AWSMarketplace/**" - - "CommonMarketplace/**" - - workflow_dispatch: - inputs: - release_version: - description: "Release version (e.g., 2026.3.2)" - required: false - type: string - -concurrency: - group: ${{ github.workflow }} - cancel-in-progress: false - -permissions: - contents: read - -jobs: - build-image: - name: Build Image - runs-on: ubuntu-24.04 - timeout-minutes: 90 - permissions: - contents: read - id-token: write - steps: - - name: Checkout repo - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - persist-credentials: false - - - 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: Retrieve secrets - id: retrieve-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@main - with: - keyvault: "gh-self-host" - secrets: "aws-marketplace-access-key-id, - aws-marketplace-secret-access-key" - - - name: Log out from Azure - uses: bitwarden/gh-actions/azure-logout@main - - - name: Set version - id: set-version - env: - RELEASE_VERSION: ${{ inputs.release_version }} - run: | - VERSION=$(jq -r '.versions.coreVersion' version.json) - if [[ -z "$VERSION" ]]; then - echo "ERROR: Failed to extract coreVersion from version.json" - exit 1 - fi - echo "version=$VERSION" >> "$GITHUB_OUTPUT" - - # Use the release version input when dispatched from the release - # pipeline. Fall back to coreVersion for other builds. - if [[ -n "$RELEASE_VERSION" ]]; then - echo "img_version=$RELEASE_VERSION" >> "$GITHUB_OUTPUT" - else - echo "img_version=$VERSION" >> "$GITHUB_OUTPUT" - fi - - - name: Set up Hashicorp Packer - uses: hashicorp/setup-packer@1aa358be5cf73883762b302a3a03abd66e75b232 # v3.1.0 - - - name: Build AWS Image - env: - AWS_ACCESS_KEY_ID: ${{ steps.retrieve-secrets.outputs.aws-marketplace-access-key-id }} - AWS_SECRET_ACCESS_KEY: ${{ steps.retrieve-secrets.outputs.aws-marketplace-secret-access-key }} - AWS_DEFAULT_REGION: "us-east-1" - AWS_IMG_VERSION: ${{ steps.set-version.outputs.img_version }} - working-directory: ./AWSMarketplace - run: | - packer version - packer init -upgrade marketplace-image.pkr.hcl - packer build marketplace-image.pkr.hcl - - - name: Cleanup orphaned instances on cancellation or failure - if: cancelled() || failure() - env: - AWS_ACCESS_KEY_ID: ${{ steps.retrieve-secrets.outputs.aws-marketplace-access-key-id }} - AWS_SECRET_ACCESS_KEY: ${{ steps.retrieve-secrets.outputs.aws-marketplace-secret-access-key }} - AWS_DEFAULT_REGION: "us-east-1" - run: | - echo "Workflow cancelled - cleaning up any orphaned resources..." - - echo "## :warning: Workflow Cancelled - Resource Cleanup" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "Searching for orphaned instances with tag: \`github-run-${{ github.run_id }}\`" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - - # Find and terminate EC2 instances tagged with this run - INSTANCE_IDS=$(aws ec2 describe-instances \ - --filters "Name=tag:GitHub_Run,Values=github-run-${{ github.run_id }}" \ - "Name=instance-state-name,Values=pending,running,stopping,stopped" \ - --query "Reservations[].Instances[].InstanceId" \ - --output text) - - if [ -n "$INSTANCE_IDS" ]; then - echo "Found orphaned instances: $INSTANCE_IDS" - echo "### Orphaned Instances Found and Terminated" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "| Instance ID | Status |" >> $GITHUB_STEP_SUMMARY - echo "|-------------|--------|" >> $GITHUB_STEP_SUMMARY - - for INSTANCE_ID in $INSTANCE_IDS; do - echo "Terminating instance: $INSTANCE_ID" - if aws ec2 terminate-instances --instance-ids "$INSTANCE_ID"; then - echo "| $INSTANCE_ID | :white_check_mark: Terminated |" >> $GITHUB_STEP_SUMMARY - else - echo "| $INSTANCE_ID | :x: Failed to terminate |" >> $GITHUB_STEP_SUMMARY - fi - done - else - echo "No orphaned instances found" - echo ":white_check_mark: No orphaned resources found - nothing to clean up" >> $GITHUB_STEP_SUMMARY - fi - - - name: Add build summary - if: success() - env: - VERSION: ${{ steps.set-version.outputs.version }} - working-directory: ./AWSMarketplace - run: | - echo "## :rocket: AWS Marketplace Image Build Complete" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "**Version:** ${VERSION}" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - - # Get artifact details from manifest - if [ -f manifest.json ]; then - AMI_ID=$(jq -r '.builds[-1].artifact_id' manifest.json) - echo "**AMI ID:** \`$AMI_ID\`" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - fi - - echo ":white_check_mark: Packer build instance was automatically cleaned up" >> $GITHUB_STEP_SUMMARY - - - name: AWS Image Cleanup - working-directory: ./AWSMarketplace - if: ${{ inputs.release_version == '' }} - env: - AWS_ACCESS_KEY_ID: ${{ steps.retrieve-secrets.outputs.aws-marketplace-access-key-id }} - AWS_SECRET_ACCESS_KEY: ${{ steps.retrieve-secrets.outputs.aws-marketplace-secret-access-key }} - AWS_DEFAULT_REGION: "us-east-1" - run: | - # Get the AMI ID from the manifest (format: "us-east-1:ami-xxxxxxxxx") - AMI_ID=$(jq -r '.builds[-1].artifact_id' manifest.json | cut -d ":" -f2) - - if [ -n "$AMI_ID" ]; then - # Find associated snapshots before deregistering - SNAPSHOT_IDS=$(aws ec2 describe-images --image-ids "$AMI_ID" \ - --query "Images[].BlockDeviceMappings[].Ebs.SnapshotId" \ - --output text 2>/dev/null || true) - - # Deregister the AMI - aws ec2 deregister-image --image-id "$AMI_ID" 2>/dev/null || true - - # Delete associated snapshots - for SNAPSHOT_ID in $SNAPSHOT_IDS; do - aws ec2 delete-snapshot --snapshot-id "$SNAPSHOT_ID" 2>/dev/null || true - done - fi - - # Update summary for non-release builds - echo "" >> $GITHUB_STEP_SUMMARY - echo "---" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo ":wastebasket: **Non-release build:** AMI \`$AMI_ID\` and snapshots were automatically cleaned up" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/release-azure.yml b/.github/workflows/release-azure.yml deleted file mode 100644 index 635c8352..00000000 --- a/.github/workflows/release-azure.yml +++ /dev/null @@ -1,179 +0,0 @@ -name: Release Azure Marketplace - -on: - push: - paths: - - "AzureMarketplace/**" - - "CommonMarketplace/**" - - workflow_dispatch: - inputs: - release_version: - description: "Release version (e.g., 2026.3.2)" - required: false - type: string - -concurrency: - group: ${{ github.workflow }} - cancel-in-progress: false - -permissions: - contents: read - -jobs: - build-image: - name: Build Image - runs-on: ubuntu-24.04 - timeout-minutes: 90 - permissions: - contents: read - id-token: write - steps: - - name: Checkout repo - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - persist-credentials: false - - - 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: Retrieve secrets - id: retrieve-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@main - with: - keyvault: "gh-self-host" - secrets: "azure-marketplace-subscription-id" - - - name: Set version - id: set-version - env: - RELEASE_VERSION: ${{ inputs.release_version }} - RUN_NUMBER: ${{ github.run_number }} - run: | - VERSION=$(jq -r '.versions.coreVersion' version.json) - if [[ -z "$VERSION" ]]; then - echo "ERROR: Failed to extract coreVersion from version.json" - exit 1 - fi - echo "version=$VERSION" >> "$GITHUB_OUTPUT" - - # Use the release version input when dispatched from the release - # pipeline. Fall back to a dev version for push builds to avoid - # colliding with published gallery image versions. - if [[ -n "$RELEASE_VERSION" ]]; then - echo "img_version=$RELEASE_VERSION" >> "$GITHUB_OUTPUT" - else - echo "img_version=0.0.$RUN_NUMBER" >> "$GITHUB_OUTPUT" - fi - - - name: Set up Hashicorp Packer - uses: hashicorp/setup-packer@1aa358be5cf73883762b302a3a03abd66e75b232 # v3.1.0 - - - name: Build Azure Image - env: - AZURE_SUBSCRIPTION_ID: ${{ steps.retrieve-secrets.outputs.azure-marketplace-subscription-id }} - AZURE_RESOURCE_GROUP: rg-marketplace - AZURE_GALLERY_NAME: bitwarden_marketplace - AZURE_GALLERY_IMAGE_NAME: "bitwarden-self-host" - AZURE_IMG_VERSION: ${{ steps.set-version.outputs.img_version }} - working-directory: ./AzureMarketplace - run: | - packer version - packer init -upgrade marketplace-image.pkr.hcl - packer build marketplace-image.pkr.hcl - - - name: Cleanup orphaned resources on cancellation or failure - if: cancelled() || failure() - env: - RESOURCE_GROUP: rg-marketplace - run: | - echo "Workflow cancelled - cleaning up any orphaned resources..." - - echo "## :warning: Workflow Cancelled - Resource Cleanup" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "Searching for orphaned resources with tag: \`github-run-${{ github.run_id }}\`" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - - # Find and delete VMs tagged with this run - VM_IDS=$(az vm list \ - --resource-group "$RESOURCE_GROUP" \ - --query "[?tags.github_run=='github-run-${{ github.run_id }}'].id" \ - --output tsv) - - if [ -n "$VM_IDS" ]; then - echo "Found orphaned VMs, deleting..." - echo "### Orphaned VMs Found and Deleted" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - for VM_ID in $VM_IDS; do - echo "Deleting VM: $VM_ID" - if az vm delete --ids "$VM_ID" --yes --force-deletion true; then - echo "| $VM_ID | :white_check_mark: Deleted |" >> $GITHUB_STEP_SUMMARY - else - echo "| $VM_ID | :x: Failed to delete |" >> $GITHUB_STEP_SUMMARY - fi - done - else - echo "No orphaned VMs found" - echo ":white_check_mark: No orphaned resources found - nothing to clean up" >> $GITHUB_STEP_SUMMARY - fi - - - name: Add build summary - if: success() - env: - VERSION: ${{ steps.set-version.outputs.version }} - working-directory: ./AzureMarketplace - run: | - echo "## :rocket: Azure Marketplace Image Build Complete" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "**Version:** ${VERSION}" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - - # Get artifact details from manifest - if [ -f manifest.json ]; then - IMAGE_ID=$(jq -r '.builds[-1].artifact_id' manifest.json) - echo "**Image ID:** \`$IMAGE_ID\`" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - fi - - echo ":white_check_mark: Packer build VM was automatically cleaned up" >> $GITHUB_STEP_SUMMARY - - - name: Azure Image Cleanup - working-directory: ./AzureMarketplace - if: ${{ inputs.release_version == '' }} - env: - RESOURCE_GROUP: rg-marketplace - GALLERY_NAME: bitwarden_marketplace - VERSION: ${{ steps.set-version.outputs.img_version }} - run: | - # Get the managed image name from manifest - IMAGE_NAME=$(jq -r '.builds[-1].custom_data.managed_image_name // empty' manifest.json) - - # Delete the gallery image version - az sig image-version delete \ - --resource-group "$RESOURCE_GROUP" \ - --gallery-name "$GALLERY_NAME" \ - --gallery-image-definition "bitwarden-self-host" \ - --gallery-image-version "$VERSION" \ - 2>/dev/null || true - - # Delete the managed image - if [ -n "$IMAGE_NAME" ]; then - az image delete \ - --resource-group "$RESOURCE_GROUP" \ - --name "$IMAGE_NAME" \ - 2>/dev/null || true - fi - - # Update summary for non-release builds - echo "" >> $GITHUB_STEP_SUMMARY - echo "---" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo ":wastebasket: **Non-release build:** Image was automatically cleaned up" >> $GITHUB_STEP_SUMMARY - - - name: Log out from Azure - if: always() - uses: bitwarden/gh-actions/azure-logout@main diff --git a/.github/workflows/release-digital-ocean.yml b/.github/workflows/release-digital-ocean.yml deleted file mode 100644 index 6fe57c74..00000000 --- a/.github/workflows/release-digital-ocean.yml +++ /dev/null @@ -1,166 +0,0 @@ -name: Release Digital Ocean 1-Click - -on: - push: - paths: - - "DigitalOceanMarketplace/**" - - "CommonMarketplace/**" - - workflow_dispatch: - inputs: - release_version: - description: "Release version (e.g., 2026.3.2)" - required: false - type: string - -concurrency: - group: ${{ github.workflow }} - cancel-in-progress: false - -permissions: - contents: read - -jobs: - build-image: - name: Build Image - runs-on: ubuntu-24.04 - timeout-minutes: 90 - permissions: - contents: read - id-token: write - steps: - - name: Checkout repo - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - persist-credentials: false - - - 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: Retrieve secrets - id: retrieve-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@main - with: - keyvault: "bitwarden-ci" - secrets: "digital-ocean-api-key" - - - name: Log out from Azure - uses: bitwarden/gh-actions/azure-logout@main - - - name: Set version - id: set-version - env: - RELEASE_VERSION: ${{ inputs.release_version }} - run: | - # Use the release version input when dispatched from the release - # pipeline. Fall back to coreVersion for other builds. - if [[ -n "$RELEASE_VERSION" ]]; then - IMG_VERSION="$RELEASE_VERSION" - else - IMG_VERSION=$(jq -r '.versions.coreVersion' version.json) - if [[ -z "$IMG_VERSION" || "$IMG_VERSION" == "null" ]]; then - echo "ERROR: Failed to extract coreVersion from version.json" - exit 1 - fi - fi - echo "img_version=$IMG_VERSION" >> "$GITHUB_OUTPUT" - - - name: Set up Hashicorp Packer - uses: hashicorp/setup-packer@1aa358be5cf73883762b302a3a03abd66e75b232 # v3.1.0 - - - name: Build Digital Ocean Image - env: - DIGITALOCEAN_TOKEN: ${{ steps.retrieve-secrets.outputs.digital-ocean-api-key }} - DIGITALOCEAN_IMG_VERSION: ${{ steps.set-version.outputs.img_version }} - working-directory: ./DigitalOceanMarketplace - run: | - packer version - packer init -upgrade marketplace-image.pkr.hcl - packer build marketplace-image.pkr.hcl - - - name: Install doctl - uses: digitalocean/action-doctl@135ac0aa0eed4437d547c6f12c364d3006b42824 # v2.5.1 - with: - token: ${{ steps.retrieve-secrets.outputs.digital-ocean-api-key }} - - - name: Cleanup orphaned droplets on cancellation - if: cancelled() - run: | - echo "Workflow cancelled - cleaning up any orphaned droplets..." - - # Write to workflow summary - echo "## :warning: Workflow Cancelled - Droplet Cleanup" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "Searching for orphaned droplets with tag: \`github-run-${{ github.run_id }}\`" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - - # Find droplets with our workflow run tag - DROPLET_IDS=$(doctl compute droplet list \ - --tag-name "github-run-${{ github.run_id }}" \ - --format ID \ - --no-header) - - if [ -n "$DROPLET_IDS" ]; then - echo "Found orphaned droplets: $DROPLET_IDS" - echo "### Orphaned Droplets Found and Deleted" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "| Droplet ID | Status |" >> $GITHUB_STEP_SUMMARY - echo "|------------|--------|" >> $GITHUB_STEP_SUMMARY - - for DROPLET_ID in $DROPLET_IDS; do - echo "Deleting droplet $DROPLET_ID..." - if doctl compute droplet delete "$DROPLET_ID" --force; then - echo "| $DROPLET_ID | :white_check_mark: Deleted |" >> $GITHUB_STEP_SUMMARY - else - echo "| $DROPLET_ID | :x: Failed to delete |" >> $GITHUB_STEP_SUMMARY - fi - done - echo "" >> $GITHUB_STEP_SUMMARY - echo ":white_check_mark: Cleanup complete" >> $GITHUB_STEP_SUMMARY - else - echo "No orphaned droplets found" - echo ":white_check_mark: No orphaned droplets found - nothing to clean up" >> $GITHUB_STEP_SUMMARY - fi - - - name: Add build summary - if: success() - env: - VERSION: ${{ steps.set-version.outputs.img_version }} - working-directory: ./DigitalOceanMarketplace - run: | - echo "## :rocket: Digital Ocean Image Build Complete" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "**Version:** ${VERSION}" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - - # Get artifact details from manifest - if [ -f manifest.json ]; then - SNAPSHOT_ID=$(jq -r '.builds[-1].artifact_id' manifest.json | cut -d ":" -f2) - SNAPSHOT_NAME=$(jq -r '.builds[-1].custom_data.snapshot_name // "N/A"' manifest.json) - echo "**Snapshot ID:** \`$SNAPSHOT_ID\`" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "**Snapshot Name:** \`$SNAPSHOT_NAME\`" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - fi - - echo ":white_check_mark: Packer build droplet was automatically cleaned up" >> $GITHUB_STEP_SUMMARY - - - name: Digital Ocean Image Cleanup - working-directory: ./DigitalOceanMarketplace - if: ${{ inputs.release_version == '' }} - run: | - # Get the ID from the snapshot build. - DO_ARTIFACT=$(jq -r '.builds[-1].artifact_id' manifest.json | cut -d ":" -f2) - - # Force remove the snapshot - doctl compute image delete "$DO_ARTIFACT" -f - - # Update summary for non-release builds - echo "" >> $GITHUB_STEP_SUMMARY - echo "---" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo ":wastebasket: **Non-release build:** Snapshot \`$DO_ARTIFACT\` was automatically cleaned up" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 05a7d2dd..00000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,541 +0,0 @@ -name: Release -run-name: Release v${{ inputs.release_version }} - -on: - workflow_dispatch: - inputs: - release_version: - description: "Release Version (example: '2025.2.1')" - required: true - -env: - _REGISTRY: ghcr.io/bitwarden - -concurrency: - group: ${{ github.workflow }} - cancel-in-progress: false - -permissions: - contents: read - -jobs: - self-host-version-check: - name: Check Self-Host Version Input - if: github.ref_name == 'main' - runs-on: ubuntu-24.04 - steps: - - name: Checkout repo - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - persist-credentials: false - - - name: Get Latest Self-Host Version - id: get-self-host - uses: bitwarden/gh-actions/get-release-version@main - with: - repository: bitwarden/self-host - - - name: Check Release Version - env: - RELEASE_VERSION: ${{ inputs.release_version }} - PREVIOUS_RELEASE_VERSION: ${{ steps.get-self-host.outputs.version }} - run: | - if [ "${RELEASE_VERSION}" == "${PREVIOUS_RELEASE_VERSION}" ]; then - echo "[!] Already released v${RELEASE_VERSION}. Please bump the version to continue." - exit 1 - fi - - - update-versions: - name: "Update versions" - runs-on: ubuntu-24.04 - 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 }} - updated_version_commit_hash: ${{ steps.push-changes.outputs.commit_hash }} - 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 # for pushing commits - - - name: Checkout Branch - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - 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 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: - NEW_VERSION: ${{ steps.get-web.outputs.version }} - run: | - OLD_VERSION=$(jq -r '.versions.webVersion' version.json) - - 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 - - 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 - - echo "tag=$NEW_VERSION" >> "$GITHUB_OUTPUT" - - - name: Update docker-compose.yml with new version - env: - CORE_VERSION: ${{ steps.update-core-version.outputs.tag }} - run: | - sed -i -e "s|lite:\${TAG:-[^}]*}|lite:\${TAG:-$CORE_VERSION}|" bitwarden-lite/docker-compose.yml - echo ":pencil: Updated docker-compose.yml TAG to $CORE_VERSION" >> "$GITHUB_STEP_SUMMARY" - - - 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 - id: push-changes - if: ${{ steps.version-changed.outputs.changes_to_commit == 'true' }} - run: | - git push - echo "commit_hash=$(git log -1 --format='%H')" >> "$GITHUB_OUTPUT" - - 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - fetch-depth: 0 - persist-credentials: false - ref: ${{ needs.update-versions.outputs.updated_version_commit_hash }} - - - name: Prepare release notes - id: prepare-release-notes - env: - 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="" - - if [ -n "${CORE_VERSION_CHANGED}" ]; then - RELEASE_NOTES+="Update Core version to [v${CORE_RELEASE_TAG}](https://github.com/bitwarden/server/releases/tag/v${CORE_RELEASE_TAG})" - fi - - if [ -n "${WEB_VERSION_CHANGED}" ]; then - if [ -n "$RELEASE_NOTES" ]; then - RELEASE_NOTES+=$'\n' - fi - RELEASE_NOTES+="Update Web version to [v${WEB_RELEASE_TAG}](https://github.com/bitwarden/clients/releases/tag/web-v${WEB_RELEASE_TAG})" - fi - - if [ -n "${KEY_CONNECTOR_VERSION_CHANGED}" ]; then - if [ -n "$RELEASE_NOTES" ]; then - RELEASE_NOTES+=$'\n' - fi - RELEASE_NOTES+="Update Key Connector version to [v${KEY_CONNECTOR_RELEASE_TAG}](https://github.com/bitwarden/key-connector/releases/tag/v${KEY_CONNECTOR_RELEASE_TAG})" - fi - - ( - echo 'RELEASE_NOTES<> "$GITHUB_OUTPUT" - - - name: Create GitHub release - uses: ncipollo/release-action@bcfe5470707e8832e12347755757cec0eb3c22af # v1.18.0 - with: - artifacts: 'bitwarden.sh, - run.sh, - bitwarden.ps1, - run.ps1, - version.json' - tag: "v${{ inputs.release_version }}" - name: "Version ${{ inputs.release_version }}" - body: ${{ steps.prepare-release-notes.outputs.RELEASE_NOTES }} - token: ${{ secrets.GITHUB_TOKEN }} - commit: ${{ needs.update-versions.outputs.updated_version_commit_hash }} - draft: false - - - release-s3: - name: Upload version.json - runs-on: ubuntu-24.04 - needs: - - update-versions - - release-github - permissions: - contents: read - id-token: write - steps: - - name: Checkout repo - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - persist-credentials: false - ref: ${{ needs.update-versions.outputs.updated_version_commit_hash }} - - - 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: Retrieve secrets - id: retrieve-secrets - uses: bitwarden/gh-actions/get-keyvault-secrets@main - with: - keyvault: "bitwarden-ci" - secrets: "aws-selfhost-version-access-id, - aws-selfhost-version-access-key, - aws-selfhost-version-bucket-name" - - - name: Log out from Azure - uses: bitwarden/gh-actions/azure-logout@main - - - name: Upload version.json to S3 bucket - 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 }} - AWS_DEFAULT_REGION: 'us-east-1' - AWS_S3_BUCKET_NAME: ${{ steps.retrieve-secrets.outputs.aws-selfhost-version-bucket-name }} - run: | - aws s3 cp version.json "$AWS_S3_BUCKET_NAME" \ - --acl "public-read" \ - --quiet - - - tag-push-latest-images: - name: Release ${{ matrix.image_name }} image - runs-on: ubuntu-24.04 - timeout-minutes: 45 - needs: - - update-versions - - release-github - env: - _PROJECT_NAME: ${{ matrix.image_name }} - permissions: - id-token: write - packages: write - strategy: - fail-fast: false - matrix: - include: - - image_name: admin - - image_name: api - - image_name: attachments - - image_name: billing - - image_name: events - - image_name: eventsprocessor - - image_name: icons - - image_name: identity - - image_name: mssql - - image_name: mssqlmigratorutility - - image_name: nginx - - image_name: notifications - - image_name: scim - - image_name: setup - - image_name: sso - - image_name: web - steps: - - name: Checkout repo - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - persist-credentials: false - - - name: Set up release tag - id: image-setup - env: - CORE_RELEASE_TAG: ${{ needs.update-versions.outputs.core_release_tag }} - WEB_RELEASE_TAG: ${{ needs.update-versions.outputs.web_release_tag }} - run: | - if [[ "${_PROJECT_NAME}" == "web" ]]; then - echo "release_tag=$WEB_RELEASE_TAG" >> "$GITHUB_OUTPUT" - else - echo "release_tag=$CORE_RELEASE_TAG" >> "$GITHUB_OUTPUT" - fi - - - name: Login to GitHub Container Registry - uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Push latest image - id: push-image - env: - RELEASE_TAG: ${{ steps.image-setup.outputs.release_tag }} - run: | - skopeo copy --all "docker://${_REGISTRY}/${_PROJECT_NAME}:${RELEASE_TAG}" "docker://${_REGISTRY}/${_PROJECT_NAME}:latest" - - # Get digests for signing - LATEST_DIGEST=$(skopeo inspect "docker://${_REGISTRY}/${_PROJECT_NAME}:latest" --format '{{.Digest}}') - echo "latest_digest=$LATEST_DIGEST" >> "$GITHUB_OUTPUT" - - - name: Install Cosign - uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0 - - - name: Sign image with Cosign - env: - LATEST_DIGEST: ${{ steps.push-image.outputs.latest_digest }} - run: cosign sign --yes "${_REGISTRY}/${_PROJECT_NAME}@$LATEST_DIGEST" - - - name: Log out of GHCR - run: docker logout ghcr.io - - - build-lite-image: - name: Build Bitwarden lite image - uses: ./.github/workflows/build-bitwarden-lite.yml - needs: update-versions - permissions: - contents: read - id-token: write - packages: write - security-events: write - with: - self_host_repo_ref: ${{ needs.update-versions.outputs.updated_version_commit_hash }} - use_latest_core_version: true - use_latest_web_version: true - secrets: inherit - - - release-bitwarden-lite: - name: Release Bitwarden lite - runs-on: ubuntu-24.04 - timeout-minutes: 30 - needs: - - update-versions - - build-lite-image - env: - _CORE_VERSION: ${{ needs.update-versions.outputs.core_release_tag }} - permissions: - id-token: write - packages: write - steps: - - name: Login to GitHub Container Registry - uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Install Cosign - uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0 - - - name: Copy version tag to latest - id: copy-lite-image - run: | - skopeo copy --all "docker://${_REGISTRY}/lite:$_CORE_VERSION" "docker://${_REGISTRY}/lite:latest" - echo ":white_check_mark: Promoted Bitwarden lite $_CORE_VERSION to latest" >> "$GITHUB_STEP_SUMMARY" - - # Get digest for signing - LATEST_DIGEST=$(skopeo inspect "docker://${_REGISTRY}/lite:latest" --format '{{.Digest}}') - echo "latest_digest=$LATEST_DIGEST" >> "$GITHUB_OUTPUT" - - - name: Sign latest image with Cosign - env: - LATEST_DIGEST: ${{ steps.copy-lite-image.outputs.latest_digest }} - run: cosign sign --yes "${_REGISTRY}/lite@$LATEST_DIGEST" - - - name: Log out of ghcr.io - run: docker logout ghcr.io - - trigger-workflows: - name: Trigger workflows - runs-on: ubuntu-24.04 - needs: - - tag-push-latest-images - - release-bitwarden-lite - 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-actions: write - - - name: Trigger release-digital-ocean workflow - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - env: - RELEASE_TAG: v${{ inputs.release_version }} - RELEASE_VERSION: ${{ inputs.release_version }} - with: - github-token: ${{ steps.app-token.outputs.token }} - script: | - await github.rest.actions.createWorkflowDispatch({ - owner: 'bitwarden', - repo: 'self-host', - workflow_id: 'release-digital-ocean.yml', - ref: process.env.RELEASE_TAG, - inputs: { release_version: process.env.RELEASE_VERSION } - }); - - - name: Trigger release-aws workflow - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - env: - RELEASE_TAG: v${{ inputs.release_version }} - RELEASE_VERSION: ${{ inputs.release_version }} - with: - github-token: ${{ steps.app-token.outputs.token }} - script: | - await github.rest.actions.createWorkflowDispatch({ - owner: 'bitwarden', - repo: 'self-host', - workflow_id: 'release-aws.yml', - ref: process.env.RELEASE_TAG, - inputs: { release_version: process.env.RELEASE_VERSION } - }); - - - name: Trigger release-azure workflow - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - env: - RELEASE_TAG: v${{ inputs.release_version }} - RELEASE_VERSION: ${{ inputs.release_version }} - with: - github-token: ${{ steps.app-token.outputs.token }} - script: | - await github.rest.actions.createWorkflowDispatch({ - owner: 'bitwarden', - repo: 'self-host', - workflow_id: 'release-azure.yml', - ref: process.env.RELEASE_TAG, - inputs: { release_version: process.env.RELEASE_VERSION } - }); -