1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-12 14:34:02 +00:00

Merge branch 'main' into DEVOPS-1573_add-web-build-script

This commit is contained in:
Matt Bishop
2024-11-21 08:45:26 -05:00
committed by GitHub
4950 changed files with 751816 additions and 152347 deletions

1
.browserslistrc Normal file
View File

@@ -0,0 +1 @@
> 0.5%, last 3 major versions, Firefox ESR, not dead

12
.checkmarx/config.yml Normal file
View File

@@ -0,0 +1,12 @@
version: 1
# Checkmarx configuration file
#
# https://checkmarx.com/resource/documents/en/34965-68549-configuring-projects-using-config-as-code-files.html
checkmarx:
scan:
configs:
sast:
presetName: "BW ASA Premium"
# Exclude spec files, and test specific files
filter: "!*.spec.ts,!**/spec/**,!apps/desktop/native-messaging-test-runner/**"

View File

@@ -0,0 +1,14 @@
{
"usage": "Documentation: https://codescene.io/docs/guides/technical/code-health.html. Template: https://codescene.io/projects/26215/config/codehealth/export/code-health-rules.json",
"rule_sets": [
{
"matching_content_path": "**/*.spec.ts",
"rules": [
{
"name": "Code Duplication",
"weight": 0.0
}
]
}
]
}

View File

@@ -12,14 +12,13 @@ storybook-static
apps/browser/config/config.js
apps/browser/src/auth/scripts/duo.js
apps/browser/src/autofill/content/autofill.js
apps/browser/webpack/manifest.js
apps/desktop/desktop_native
apps/desktop/src/auth/scripts/duo.js
apps/web/config.js
apps/web/scripts/*.js
apps/web/src/theme.js
apps/web/tailwind.config.js
apps/cli/config/config.js

View File

@@ -16,11 +16,12 @@
},
"extends": [
"eslint:recommended",
"plugin:@angular-eslint/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:import/recommended",
"plugin:import/typescript",
"prettier",
"plugin:rxjs/recommended",
"prettier",
"plugin:storybook/recommended"
],
"settings": {
@@ -34,20 +35,28 @@
}
},
"rules": {
"@typescript-eslint/no-explicit-any": "off", // TODO: This should be re-enabled
"@typescript-eslint/no-unused-vars": ["error", { "args": "none" }],
"@angular-eslint/component-class-suffix": 0,
"@angular-eslint/contextual-lifecycle": 0,
"@angular-eslint/directive-class-suffix": 0,
"@angular-eslint/no-empty-lifecycle-method": 0,
"@angular-eslint/no-host-metadata-property": 0,
"@angular-eslint/no-input-rename": 0,
"@angular-eslint/no-inputs-metadata-property": 0,
"@angular-eslint/no-output-native": 0,
"@angular-eslint/no-output-on-prefix": 0,
"@angular-eslint/no-output-rename": 0,
"@angular-eslint/no-outputs-metadata-property": 0,
"@angular-eslint/use-lifecycle-interface": "error",
"@angular-eslint/use-pipe-transform-interface": 0,
"@typescript-eslint/explicit-member-accessibility": [
"error",
{
"accessibility": "no-public"
}
],
"@typescript-eslint/no-this-alias": [
"error",
{
"allowedNames": ["self"]
}
{ "accessibility": "no-public" }
],
"@typescript-eslint/no-explicit-any": "off", // TODO: This should be re-enabled
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/no-misused-promises": ["error", { "checksVoidReturn": false }],
"@typescript-eslint/no-this-alias": ["error", { "allowedNames": ["self"] }],
"@typescript-eslint/no-unused-vars": ["error", { "args": "none" }],
"no-console": "error",
"import/no-unresolved": "off", // TODO: Look into turning off once each package is an actual package.
"import/order": [
@@ -72,7 +81,7 @@
"pathGroupsExcludedImportTypes": ["builtin"]
}
],
"rxjs-angular/prefer-takeuntil": "error",
"rxjs-angular/prefer-takeuntil": ["error", { "alias": ["takeUntilDestroyed"] }],
"rxjs/no-exposed-subjects": ["error", { "allowProtected": true }],
"no-restricted-syntax": [
"error",
@@ -91,6 +100,11 @@
"error",
{
"zones": [
{
"target": ["libs/**/*"],
"from": ["apps/**/*"],
"message": "Libs should not import app-specific code."
},
{
// avoid specific frameworks or large dependencies in common
"target": "./libs/common/**/*",
@@ -102,18 +116,33 @@
// Node
"./libs/node/**/*",
//Generator
"./libs/tools/generator/components/**/*",
"./libs/tools/generator/core/**/*",
"./libs/tools/generator/extensions/**/*",
// Import/export
"./libs/importer/**/*",
"./libs/exporter/**/*"
"./libs/tools/export/vault-export/vault-export-core/**/*"
]
},
{
// avoid import of unexported state objects
"target": [
"!(libs)/**/*",
"libs/!(common)/**/*",
"libs/common/!(src)/**/*",
"libs/common/src/!(platform)/**/*",
"libs/common/src/platform/!(state)/**/*"
],
"from": ["./libs/common/src/platform/state/**/*"],
// allow module index import
"except": ["**/state/index.ts"]
}
]
}
],
"no-restricted-imports": [
"error",
{ "patterns": ["src/**/*"], "paths": ["@fluffy-spoon/substitute"] }
]
"no-restricted-imports": ["error", { "patterns": ["src/**/*"] }]
}
},
{
@@ -135,6 +164,15 @@
"tailwindcss/no-contradicting-classname": "error"
}
},
{
"files": ["libs/admin-console/src/**/*.ts"],
"rules": {
"no-restricted-imports": [
"error",
{ "patterns": ["@bitwarden/admin-console/*", "src/**/*"] }
]
}
},
{
"files": ["libs/angular/src/**/*.ts"],
"rules": {
@@ -147,6 +185,12 @@
"no-restricted-imports": ["error", { "patterns": ["@bitwarden/auth/*", "src/**/*"] }]
}
},
{
"files": ["libs/billing/src/**/*.ts"],
"rules": {
"no-restricted-imports": ["error", { "patterns": ["@bitwarden/billing/*", "src/**/*"] }]
}
},
{
"files": ["libs/common/src/**/*.ts"],
"rules": {
@@ -163,9 +207,66 @@
}
},
{
"files": ["libs/exporter/src/**/*.ts"],
"files": ["libs/tools/generator/components/src/**/*.ts"],
"rules": {
"no-restricted-imports": ["error", { "patterns": ["@bitwarden/exporter/*", "src/**/*"] }]
"no-restricted-imports": [
"error",
{ "patterns": ["@bitwarden/generator-components/*", "src/**/*"] }
]
}
},
{
"files": ["libs/tools/generator/core/src/**/*.ts"],
"rules": {
"no-restricted-imports": [
"error",
{ "patterns": ["@bitwarden/generator-core/*", "src/**/*"] }
]
}
},
{
"files": ["libs/tools/generator/extensions/history/src/**/*.ts"],
"rules": {
"no-restricted-imports": [
"error",
{ "patterns": ["@bitwarden/generator-history/*", "src/**/*"] }
]
}
},
{
"files": ["libs/tools/generator/extensions/legacy/src/**/*.ts"],
"rules": {
"no-restricted-imports": [
"error",
{ "patterns": ["@bitwarden/generator-legacy/*", "src/**/*"] }
]
}
},
{
"files": ["libs/tools/generator/extensions/navigation/src/**/*.ts"],
"rules": {
"no-restricted-imports": [
"error",
{ "patterns": ["@bitwarden/generator-navigation/*", "src/**/*"] }
]
}
},
{
"files": ["libs/tools/export/vault-export/vault-export-core/src/**/*.ts"],
"rules": {
"no-restricted-imports": [
"error",
{ "patterns": ["@bitwarden/vault-export-core/*", "src/**/*"] }
]
}
},
{
"files": ["libs/tools/export/vault-export/vault-export-ui/src/**/*.ts"],
"rules": {
"no-restricted-imports": [
"error",
{ "patterns": ["@bitwarden/vault-export-ui/*", "src/**/*"] }
]
}
},
{
@@ -180,11 +281,94 @@
"no-restricted-imports": ["error", { "patterns": ["@bitwarden/node/*", "src/**/*"] }]
}
},
{
"files": ["libs/platform/src/**/*.ts"],
"rules": {
"no-restricted-imports": ["error", { "patterns": ["@bitwarden/platform/*", "src/**/*"] }]
}
},
{
"files": ["libs/tools/send/send-ui/src/**/*.ts"],
"rules": {
"no-restricted-imports": ["error", { "patterns": ["@bitwarden/send-ui/*", "src/**/*"] }]
}
},
{
"files": ["libs/tools/card/src/**/*.ts"],
"rules": {
"no-restricted-imports": ["error", { "patterns": ["@bitwarden/tools-card/*", "src/**/*"] }]
}
},
{
"files": ["libs/vault/src/**/*.ts"],
"rules": {
"no-restricted-imports": ["error", { "patterns": ["@bitwarden/vault/*", "src/**/*"] }]
}
},
{
"files": ["apps/browser/src/**/*.ts", "libs/**/*.ts"],
"excludedFiles": [
"apps/browser/src/autofill/{content,notification}/**/*.ts",
"apps/browser/src/**/background/**/*.ts", // It's okay to have long lived listeners in the background
"apps/browser/src/platform/background.ts"
],
"rules": {
"no-restricted-syntax": [
"error",
{
"message": "Using addListener in the browser popup produces a memory leak in Safari, use `BrowserApi.addListener` instead",
// This selector covers events like chrome.storage.onChange & chrome.runtime.onMessage
"selector": "CallExpression > [object.object.object.name='chrome'][property.name='addListener']"
},
{
"message": "Using addListener in the browser popup produces a memory leak in Safari, use `BrowserApi.addListener` instead",
// This selector covers events like chrome.storage.local.onChange
"selector": "CallExpression > [object.object.object.object.name='chrome'][property.name='addListener']"
}
]
}
},
{
"files": ["**/*.ts"],
"excludedFiles": ["**/platform/**/*.ts"],
"rules": {
"no-restricted-imports": [
"error",
{
"patterns": [
"**/platform/**/internal", // General internal pattern
// All features that have been converted to barrel files
"**/platform/messaging/**"
]
}
]
}
},
{
"files": ["bitwarden_license/bit-common/src/**/*.ts"],
"rules": {
"no-restricted-imports": ["error", { "patterns": ["@bitwarden/bit-common/*", "src/**/*"] }]
}
},
{
"files": ["apps/**/*.ts"],
"rules": {
// Catches static imports
"no-restricted-imports": [
"error",
{
"patterns": ["biwarden_license/**", "@bitwarden/bit-common/*", "@bitwarden/bit-web/*"]
}
],
// Catches dynamic imports, e.g. in routing modules where modules are lazy-loaded
"no-restricted-syntax": [
"error",
{
"message": "Don't import Bitwarden licensed code into OSS code.",
"selector": "ImportExpression > Literal.source[value=/.*(bitwarden_license|bit-common|bit-web).*/]"
}
]
}
}
]
}

View File

@@ -22,3 +22,6 @@
193434461dbd9c48fe5dcbad95693470aec422ac
# Jslib: Monorepository https://github.com/bitwarden/clients/pull/2824/commits/d7492e3cf320410e74ebd0e0675ab994e64bd01a
d7492e3cf320410e74ebd0e0675ab994e64bd01a
# All Clients: Apply Prettier https://github.com/bitwarden/clients/pull/7014
28de9439beb87133c8683434df952a0c0be94100

93
.github/CODEOWNERS vendored
View File

@@ -1,13 +1,12 @@
# Please sort lines alphabetically, this will ensure we don't accidentally add duplicates.
# Please sort into logical groups with comment headers. Sort groups in order of specificity.
# For example, default owners should always be the first group.
# Sort lines alphabetically within these groups to avoid accidentally adding duplicates.
#
# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
# The following owners will be the default owners for everything in the repo.
# Unless a later match takes precedence
* @bitwarden/tech-leads
## Secrets Manager team files ##
bitwarden_license/bit-web/src/app/secrets-manager @bitwarden/team-secrets-manager-dev
apps/web/src/app/secrets-manager/ @bitwarden/team-secrets-manager-dev
## Auth team files ##
apps/browser/src/auth @bitwarden/team-auth-dev
@@ -29,8 +28,17 @@ apps/web/src/app/tools @bitwarden/team-tools-dev
libs/angular/src/tools @bitwarden/team-tools-dev
libs/common/src/models/export @bitwarden/team-tools-dev
libs/common/src/tools @bitwarden/team-tools-dev
libs/exporter @bitwarden/team-tools-dev
libs/importer @bitwarden/team-tools-dev
libs/tools @bitwarden/team-tools-dev
bitwarden_license/bit-web/src/app/tools @bitwarden/team-tools-dev
bitwarden_license/bit-common/src/tools @bitwarden/team-tools-dev
## Localization/Crowdin (Tools team)
apps/browser/src/_locales @bitwarden/team-tools-dev
apps/browser/store/locales @bitwarden/team-tools-dev
apps/cli/src/locales @bitwarden/team-tools-dev
apps/desktop/src/locales @bitwarden/team-tools-dev
apps/web/src/locales @bitwarden/team-tools-dev
## Vault team files ##
apps/browser/src/vault @bitwarden/team-vault-dev
@@ -47,21 +55,30 @@ apps/cli/src/admin-console @bitwarden/team-admin-console-dev
apps/desktop/src/admin-console @bitwarden/team-admin-console-dev
apps/web/src/app/admin-console @bitwarden/team-admin-console-dev
bitwarden_license/bit-web/src/app/admin-console @bitwarden/team-admin-console-dev
bitwarden_license/bit-cli/src/admin-console @bitwarden/team-admin-console-dev
libs/angular/src/admin-console @bitwarden/team-admin-console-dev
libs/common/src/admin-console @bitwarden/team-admin-console-dev
libs/admin-console @bitwarden/team-admin-console-dev
## Billing team files ##
apps/browser/src/billing @bitwarden/team-billing-dev
apps/web/src/app/billing @bitwarden/team-billing-dev
libs/angular/src/billing @bitwarden/team-billing-dev
libs/common/src/billing @bitwarden/team-billing-dev
libs/billing @bitwarden/team-billing-dev
bitwarden_license/bit-web/src/app/billing @bitwarden/team-billing-dev
## Platform team files ##
apps/browser/src/platform @bitwarden/team-platform-dev
apps/cli/src/platform @bitwarden/team-platform-dev
apps/desktop/macos @bitwarden/team-platform-dev
apps/desktop/src/platform @bitwarden/team-platform-dev
apps/web/src/app/platform @bitwarden/team-platform-dev
libs/angular/src/platform @bitwarden/team-platform-dev
libs/common/src/platform @bitwarden/team-platform-dev
libs/common/spec @bitwarden/team-platform-dev
libs/common/src/state-migrations @bitwarden/team-platform-dev
libs/platform @bitwarden/team-platform-dev
# Node-specifc platform files
libs/node @bitwarden/team-platform-dev
# Web utils used across app and connectors
@@ -73,35 +90,63 @@ apps/web/src/translation-constants.ts @bitwarden/team-platform-dev
## Autofill team files ##
apps/browser/src/autofill @bitwarden/team-autofill-dev
apps/desktop/src/autofill @bitwarden/team-autofill-dev
libs/common/src/autofill @bitwarden/team-autofill-dev
apps/desktop/macos/autofill-extension @bitwarden/team-autofill-dev
# DuckDuckGo integration
apps/desktop/native-messaging-test-runner @bitwarden/team-autofill-dev
apps/desktop/src/services/native-message-handler.service.ts @bitwarden/team-autofill-dev
## Component Library ##
.storybook @bitwarden/team-platform-dev
libs/components @bitwarden/team-platform-dev
.storybook @bitwarden/team-design-system
libs/components @bitwarden/team-design-system
apps/browser/src/platform/popup/layout @bitwarden/team-design-system
apps/web/src/app/layouts @bitwarden/team-design-system
## Desktop native module ##
apps/desktop/desktop_native @bitwarden/team-platform-dev
## Multiple file owners ##
apps/browser/package.json
apps/browser/src/manifest.json
apps/browser/src/manifest.v3.json
## Key management team files ##
apps/desktop/src/key-management @bitwarden/team-key-management-dev
apps/web/src/app/key-management @bitwarden/team-key-management-dev
apps/browser/src/key-management @bitwarden/team-key-management-dev
apps/cli/src/key-management @bitwarden/team-key-management-dev
libs/key-management @bitwarden/team-key-management-dev
apps/cli/package.json
apps/desktop/package.json
apps/desktop/src/package-lock.json
apps/desktop/src/package.json
/apps/web/config
/apps/web/package.json
package-lock.json
apps/desktop/destkop_native/core/src/biometric/ @bitwarden/team-key-management-dev
apps/desktop/src/services/native-messaging.service.ts @bitwarden/team-key-management-dev
apps/browser/src/background/nativeMessaging.background.ts @bitwarden/team-key-management-dev
## Locales ##
apps/browser/src/_locales/en/messages.json
apps/browser/store/locales/en
apps/cli/src/locales/en/messages.json
apps/desktop/src/locales/en/messages.json
apps/web/src/locales/en/messages.json
## DevOps team files ##
/.github/workflows @bitwarden/dept-devops
## Ssh agent temporary co-codeowner
apps/desktop/desktop_native/core/src/ssh_agent @bitwarden/team-platform-dev @bitwarden/wg-ssh-keys
## BRE team owns these workflows ##
.github/workflows/brew-bump-desktop.yml @bitwarden/dept-bre
.github/workflows/deploy-web.yml @bitwarden/dept-bre
.github/workflows/publish-cli.yml @bitwarden/dept-bre
.github/workflows/publish-desktop.yml @bitwarden/dept-bre
.github/workflows/publish-web.yml @bitwarden/dept-bre
.github/workflows/retrieve-current-desktop-rollout.yml @bitwarden/dept-bre
.github/workflows/staged-rollout-desktop.yml @bitwarden/dept-bre
## Shared ownership workflows ##
.github/workflows/release-browser.yml
.github/workflows/release-cli.yml
.github/workflows/release-desktop-beta.yml
.github/workflows/release-desktop.yml
.github/workflows/release-web.yml
.github/workflows/version-auto-bump.yml
.github/workflows/version-bump.yml
## Docker files have shared ownership ##
**/Dockerfile
**/*.Dockerfile
**/.dockerignore
**/entrypoint.sh

View File

@@ -90,4 +90,4 @@ body:
description: |
Issue tracking information
options:
- label: I understand that work is tracked outside of Github. A PR will be linked to this issue should one be opened to address it, but Bitwarden doesn't use fields like "assigned", "milestone", or "project" to track progress.
- label: I understand that work is tracked outside of GitHub. A PR will be linked to this issue should one be opened to address it, but Bitwarden doesn't use fields like "assigned", "milestone", or "project" to track progress.

View File

@@ -1,33 +1,35 @@
## Type of change
## 🎟️ Tracking
<!-- (mark with an `X`) -->
<!-- Paste the link to the Jira or GitHub issue or otherwise describe / point to where this change is coming from. -->
```
- [ ] Bug fix
- [ ] New feature development
- [ ] Tech debt (refactoring, code cleanup, dependency upgrades, etc)
- [ ] Build/deploy pipeline (DevOps)
- [ ] Other
```
## 📔 Objective
## Objective
<!-- Describe what the purpose of this PR is, for example what bug you're fixing or new feature you're adding. -->
<!--Describe what the purpose of this PR is. For example: what bug you're fixing or what new feature you're adding-->
## 📸 Screenshots
## Code changes
<!-- Required for any UI changes; delete if not applicable. Use fixed width images for better display. -->
<!--Explain the changes you've made to each file or major component. This should help the reviewer understand your changes-->
<!--Also refer to any related changes or PRs in other repositories-->
## ⏰ Reminders before review
- **file.ext:** Description of what was changed and why
- Contributor guidelines followed
- All formatters and local linters executed and passed
- Written new unit and / or integration tests where applicable
- Protected functional changes with optionality (feature flags)
- Used internationalization (i18n) for all UI strings
- CI builds passed
- Communicated to DevOps any deployment requirements
- Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team
## Screenshots
## 🦮 Reviewer guidelines
<!--Required for any UI changes. Delete if not applicable-->
<!-- Suggested interactions but feel free to use (or not) as you desire! -->
## Before you submit
- Please add **unit tests** where it makes sense to do so (encouraged but not required)
- If this change requires a **documentation update** - notify the documentation team
- If this change has particular **deployment requirements** - notify the DevOps team
- Ensure that all UI additions follow [WCAG AA requirements](https://contributing.bitwarden.com/contributing/accessibility/)
- 👍 (`:+1:`) or similar for great changes
- 📝 (`:memo:`) or (`:information_source:`) for notes or general info
- ❓ (`:question:`) for questions
- 🤔 (`:thinking:`) or 💭 (`:thought_balloon:`) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion
- 🎨 (`:art:`) for suggestions / improvements
- ❌ (`:x:`) or ⚠️ (`:warning:`) for more significant problems or concerns needing attention
- 🌱 (`:seedling:`) or ♻️ (`:recycle:`) for future improvements or indications of technical debt
- ⛏ (`:pick:`) for minor or nitpick changes

2
.github/codecov.yml vendored Normal file
View File

@@ -0,0 +1,2 @@
ignore:
- "**/*.spec.ts" # Tests

277
.github/renovate.json vendored
View File

@@ -1,55 +1,272 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base",
":combinePatchMinorReleases",
":dependencyDashboard",
":maintainLockFilesWeekly",
":pinAllExceptPeerDependencies",
":rebaseStalePrs",
"schedule:weekends",
":separateMajorReleases"
],
"prConcurrentLimit": 3,
"extends": ["github>bitwarden/renovate-config"],
"enabledManagers": ["cargo", "github-actions", "npm"],
"packageRules": [
{
"groupName": "cargo minor",
"matchManagers": ["cargo"],
"matchUpdateTypes": ["minor", "patch"]
},
{
"groupName": "gh minor",
"matchManagers": ["github-actions"],
"matchUpdateTypes": ["minor", "patch"]
},
{
"groupName": "npm minor",
"matchManagers": ["npm"],
"matchUpdateTypes": ["minor", "patch"]
"matchManagers": ["github-actions"],
"commitMessagePrefix": "[deps] DevOps:"
},
{
"matchPackageNames": ["typescript"],
"matchManagers": ["cargo"],
"commitMessagePrefix": "[deps] Platform:"
},
{
"groupName": "napi",
"matchPackageNames": ["napi", "napi-build", "napi-derive"]
},
{
"matchPackageNames": ["typescript", "zone.js"],
"matchUpdateTypes": ["major", "minor"],
"description": "Determined by Angular",
"enabled": false
},
{
"matchPackageNames": ["typescript"],
"matchPackageNames": ["typescript", "zone.js"],
"matchUpdateTypes": "patch"
},
{
"groupName": "jest",
"matchPackageNames": ["@types/jest", "jest", "ts-jest", "jest-preset-angular"],
"matchUpdateTypes": "major"
},
{
"groupName": "macOS/iOS bindings",
"matchPackageNames": ["core-foundation", "security-framework", "security-framework-sys"]
},
{
"matchPackageNames": [
"base64-loader",
"buffer",
"bufferutil",
"core-js",
"css-loader",
"html-loader",
"mini-css-extract-plugin",
"ngx-infinite-scroll",
"postcss",
"postcss-loader",
"process",
"sass",
"sass-loader",
"style-loader",
"ts-loader",
"url",
"util"
],
"description": "Admin Console owned dependencies",
"commitMessagePrefix": "[deps] AC:",
"reviewers": ["team:team-admin-console-dev"]
},
{
"matchPackageNames": ["qrious"],
"description": "Auth owned dependencies",
"commitMessagePrefix": "[deps] Auth:",
"reviewers": ["team:team-auth-dev"]
},
{
"matchPackageNames": [
"@webcomponents/custom-elements",
"concurrently",
"cross-env",
"del",
"gulp",
"gulp-if",
"gulp-json-editor",
"gulp-replace",
"gulp-zip",
"nord",
"patch-package",
"prettier",
"prettier-plugin-tailwindcss",
"rimraf",
"tabbable",
"tldts",
"wait-on"
],
"description": "Autofill owned dependencies",
"commitMessagePrefix": "[deps] Autofill:",
"reviewers": ["team:team-autofill-dev"]
},
{
"matchPackageNames": ["braintree-web-drop-in"],
"description": "Billing owned dependencies",
"commitMessagePrefix": "[deps] Billing:",
"reviewers": ["team:team-billing-dev"]
},
{
"matchPackageNames": [
"@babel/core",
"@babel/preset-env",
"@electron/notarize",
"@electron/rebuild",
"@ngtools/webpack",
"@types/chrome",
"@types/firefox-webext-browser",
"@types/glob",
"@types/jquery",
"@types/lowdb",
"@types/node",
"@types/node-forge",
"@types/node-ipc",
"@yao-pkg",
"babel-loader",
"browserslist",
"copy-webpack-plugin",
"electron",
"electron-builder",
"electron-log",
"electron-reload",
"electron-store",
"electron-updater",
"html-webpack-injector",
"html-webpack-plugin",
"lowdb",
"node-forge",
"node-ipc",
"pkg",
"rxjs",
"tsconfig-paths-webpack-plugin",
"type-fest",
"typescript",
"webpack",
"webpack-cli",
"webpack-dev-server",
"webpack-node-externals"
],
"description": "Platform owned dependencies",
"commitMessagePrefix": "[deps] Platform:",
"reviewers": ["team:team-platform-dev"]
},
{
"matchPackageNames": [
"@angular-devkit/build-angular",
"@angular/animations",
"@angular/cdk",
"@angular/cli",
"@angular/common",
"@angular/compiler",
"@angular/compiler-cli",
"@angular/core",
"@angular/forms",
"@angular/platform",
"@angular/compiler",
"@angular/router",
"@compodoc/compodoc",
"@ng-select/ng-select",
"@storybook/addon-a11y",
"@storybook/addon-actions",
"@storybook/addon-designs",
"@storybook/addon-essentials",
"@storybook/addon-links",
"@storybook/angular",
"@types/react",
"autoprefixer",
"bootstrap",
"chromatic",
"jquery",
"ngx-toastr",
"popper.js",
"react",
"react-dom",
"remark-gfm",
"storybook",
"tailwindcss",
"zone.js"
],
"description": "Component library owned dependencies",
"commitMessagePrefix": "[deps] Design System:",
"reviewers": ["team:team-design-system"]
},
{
"matchPackageNames": [
"@angular-eslint/eslint-plugin",
"@angular-eslint/eslint-plugin-template",
"@angular-eslint/template-parser",
"@types/jest",
"@typescript-eslint/eslint-plugin",
"@typescript-eslint/parser",
"eslint",
"eslint-config-prettier",
"eslint-import-resolver-typescript",
"eslint-plugin-import",
"eslint-plugin-rxjs",
"eslint-plugin-rxjs-angular",
"eslint-plugin-storybook",
"eslint-plugin-tailwindcss",
"husky",
"jest-junit",
"jest-mock-extended",
"jest-preset-angular",
"lint-staged",
"ts-jest"
],
"description": "Secrets Manager owned dependencies",
"commitMessagePrefix": "[deps] SM:",
"reviewers": ["team:team-secrets-manager-dev"]
},
{
"matchPackageNames": [
"@microsoft/signalr-protocol-msgpack",
"@microsoft/signalr",
"@types/jsdom",
"@types/papaparse",
"@types/zxcvbn",
"jsdom",
"jszip",
"oidc-client-ts",
"papaparse",
"utf-8-validate",
"zxcvbn"
],
"description": "Tools owned dependencies",
"commitMessagePrefix": "[deps] Tools:",
"reviewers": ["team:team-tools-dev"]
},
{
"matchPackageNames": [
"@koa/multer",
"@koa/router",
"@types/inquirer",
"@types/koa",
"@types/koa__multer",
"@types/koa__router",
"@types/koa-bodyparser",
"@types/koa-json",
"@types/lunr",
"@types/node-fetch",
"@types/proper-lockfile",
"@types/retry",
"chalk",
"commander",
"form-data",
"https-proxy-agent",
"inquirer",
"koa",
"koa-bodyparser",
"koa-json",
"lunr",
"multer",
"node-fetch",
"open",
"proper-lockfile",
"qrcode-parser"
],
"description": "Vault owned dependencies",
"commitMessagePrefix": "[deps] Vault:",
"reviewers": ["team:team-vault-dev"]
},
{
"matchPackageNames": ["@types/argon2-browser", "argon2", "argon2-browser", "big-integer"],
"description": "Key Management owned dependencies",
"commitMessagePrefix": "[deps] KM:",
"reviewers": ["team:team-key-management-dev"]
}
],
"ignoreDeps": [
"@types/koa-bodyparser",
"bootstrap",
"electron-builder",
"electron",
"node-ipc",
"regedit",
"zone.js"
]
"ignoreDeps": ["@types/koa-bodyparser", "bootstrap", "node-ipc", "node", "npm"]
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -5,26 +5,16 @@
./apps/browser/store/windows/Assets
./bitwarden_license/README.md
./libs/angular/src/directives/cipherListVirtualScroll.directive.ts
./libs/angular/src/scss/webfonts/Open_Sans-italic-700.woff
./libs/angular/src/scss/webfonts/Open_Sans-normal-300.woff
./libs/angular/src/scss/webfonts/Open_Sans-normal-700.woff
./libs/angular/src/scss/webfonts/Open_Sans-italic-300.woff
./libs/angular/src/scss/webfonts/Open_Sans-italic-600.woff
./libs/angular/src/scss/webfonts/Open_Sans-italic-800.woff
./libs/angular/src/scss/webfonts/Open_Sans-italic-400.woff
./libs/angular/src/scss/webfonts/Open_Sans-normal-600.woff
./libs/angular/src/scss/webfonts/Open_Sans-normal-800.woff
./libs/angular/src/scss/webfonts/Open_Sans-normal-400.woff
./libs/angular/src/validators/inputsFieldMatch.validator.ts
./libs/angular/src/validators/notAllowedValueAsync.validator.ts
./libs/angular/src/services/theming/themeBuilder.ts
./libs/common/src/misc/nodeUtils.ts
./libs/common/src/misc/linkedFieldOption.decorator.ts
./libs/common/src/misc/serviceUtils.ts
./libs/common/src/misc/serviceUtils.spec.ts
./libs/common/src/abstractions/anonymousHub.service.ts
./libs/common/src/services/anonymousHub.service.ts
./libs/admin-console/README.md
./libs/auth/README.md
./libs/billing/README.md
./libs/common/src/tools/integration/README.md
./libs/platform/README.md
./libs/key-management/README.md
./libs/tools/README.md
./libs/tools/export/vault-export/README.md
./libs/tools/send/README.md
./libs/tools/card/README.md
./libs/vault/README.md
./README.md
./LICENSE_BITWARDEN.txt
@@ -41,22 +31,11 @@
./apps/desktop/resources/appx/Wide310x150Logo.png
./apps/desktop/resources/appx/Square44x44Logo.png
./apps/desktop/README.md
./apps/desktop/desktop_native/Cargo.toml
./apps/desktop/desktop_native/Cargo.lock
./apps/cli/stores/chocolatey/tools/VERIFICATION.txt
./apps/cli/README.md
./apps/browser/README.md
./apps/browser/store/windows/AppxManifest.xml
./apps/browser/src/background/nativeMessaging.background.ts
./apps/browser/src/background/models/addLoginRuntimeMessage.ts
./apps/browser/src/background/models/addChangePasswordQueueMessage.ts
./apps/browser/src/background/models/addLoginQueueMessage.ts
./apps/browser/src/background/models/changePasswordRuntimeMessage.ts
./apps/browser/src/background/models/notificationQueueMessage.ts
./apps/browser/src/background/models/notificationQueueMessageType.ts
./apps/browser/src/background/models/lockedVaultPendingNotificationsItem.ts
./apps/browser/src/background/webRequest.background.ts
./apps/browser/src/popup/services/debounceNavigationService.ts
./apps/browser/src/models/browserComponentState.ts
./apps/browser/src/models/browserSendComponentState.ts
./apps/browser/src/models/browserGroupingsComponentState.ts

View File

@@ -1,10 +1,9 @@
---
name: Auto Update Branch
on:
push:
branches:
- 'master'
- 'main'
- 'rc'
paths:
- 'apps/web/**'
@@ -29,7 +28,7 @@ jobs:
run: echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: 'eu-web-${{ steps.setup.outputs.branch }}'
fetch-depth: 0

View File

@@ -1,4 +1,3 @@
---
name: Automatic issue responses
on:
issues:
@@ -7,7 +6,7 @@ on:
jobs:
close-issue:
name: 'Close issue with automatic response'
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
permissions:
issues: write
steps:

View File

@@ -1,4 +1,3 @@
---
name: Automatic pull request responses
on:
pull_request:
@@ -7,7 +6,7 @@ on:
jobs:
close-issue:
name: 'Close pull request with automatic response'
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
permissions:
pull-requests: write
steps:

View File

@@ -1,41 +0,0 @@
---
name: Bump CLI Formula
on:
push:
tags:
- cli-v**
workflow_dispatch:
defaults:
run:
shell: bash
jobs:
update-desktop-cask:
name: Update Bitwarden CLI Formula
runs-on: macos-11
steps:
- name: Login to Azure
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
keyvault: "bitwarden-ci"
secrets: "brew-bump-workflow-pat"
- name: Update Homebrew formula
uses: dawidd6/action-homebrew-bump-formula@d3667e5ae14df19579e4414897498e3e88f2f458 # v3.10.0
with:
# Required, custom GitHub access token with the 'public_repo' and 'workflow' scopes
token: ${{ steps.retrieve-secrets.outputs.brew-bump-workflow-pat }}
org: bitwarden
tap: Homebrew/homebrew-core
formula: bitwarden-cli
tag: ${{ github.ref }}
revision: ${{ github.sha }}
force: true

View File

@@ -1,4 +1,3 @@
---
name: Bump Desktop Cask
on:
@@ -14,16 +13,16 @@ defaults:
jobs:
update-desktop-cask:
name: Update Bitwarden Desktop Cask
runs-on: macos-11
runs-on: macos-13
steps:
- name: Login to Azure
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "brew-bump-workflow-pat"

View File

@@ -1,8 +1,8 @@
---
name: Build Browser
on:
pull_request:
pull_request_target:
types: [opened, synchronize]
branches-ignore:
- 'l10n_master'
- 'cf-pages'
@@ -10,55 +10,53 @@ on:
- 'apps/browser/**'
- 'libs/**'
- '*'
- '!libs/importer'
- '!*.md'
- '!*.txt'
push:
branches:
- 'master'
- 'main'
- 'rc'
- 'hotfix-rc-browser'
paths:
- 'apps/browser/**'
- 'libs/**'
- '*'
- '!libs/importer'
- '!*.md'
- '!*.txt'
- '.github/workflows/build-browser.yml'
workflow_call:
inputs: {}
workflow_dispatch:
inputs: {}
inputs:
sdk_branch:
description: "Custom SDK branch"
required: false
type: string
defaults:
run:
shell: bash
jobs:
cloc:
name: CLOC
runs-on: ubuntu-22.04
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Set up cloc
run: |
sudo apt update
sudo apt -y install cloc
- name: Print lines of code
run: cloc --include-lang TypeScript,JavaScript,HTML,Sass,CSS --vcs git
check-run:
name: Check PR run
uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main
setup:
name: Setup
runs-on: ubuntu-22.04
needs:
- check-run
outputs:
repo_url: ${{ steps.gen_vars.outputs.repo_url }}
adj_build_number: ${{ steps.gen_vars.outputs.adj_build_number }}
node_version: ${{ steps.retrieve-node-version.outputs.node_version }}
steps:
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Get Package Version
id: gen_vars
run: |
@@ -68,6 +66,14 @@ jobs:
echo "repo_url=$repo_url" >> $GITHUB_OUTPUT
echo "adj_build_number=$adj_build_num" >> $GITHUB_OUTPUT
- name: Get Node Version
id: retrieve-node-version
working-directory: ./
run: |
NODE_NVMRC=$(cat .nvmrc)
NODE_VERSION=${NODE_NVMRC/v/''}
echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT
locales-test:
name: Locales Test
@@ -78,8 +84,10 @@ jobs:
run:
working-directory: apps/browser
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Testing locales - extName length
run: |
@@ -114,27 +122,24 @@ jobs:
- locales-test
env:
_BUILD_NUMBER: ${{ needs.setup.outputs.adj_build_number }}
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Set up Node
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
node-version: '18'
- name: Install node-gyp
run: |
npm install -g node-gyp
node-gyp install $(node -v)
node-version: ${{ env._NODE_VERSION }}
- name: Print environment
run: |
node --version
npm --version
node-gyp --version
- name: Build sources for reviewers
run: |
@@ -163,168 +168,231 @@ jobs:
zip -r browser-source.zip browser-source
- name: NPM setup
run: npm ci
working-directory: browser-source/
- name: Build
run: npm run dist
working-directory: browser-source/apps/browser
# - name: Build Manifest v3
# run: npm run dist:mv3
# working-directory: browser-source/apps/browser
- name: Gulp
run: gulp ci
working-directory: browser-source/apps/browser
- name: Upload Opera artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
with:
name: dist-opera-${{ env._BUILD_NUMBER }}.zip
path: browser-source/apps/browser/dist/dist-opera.zip
if-no-files-found: error
# - name: Upload Opera MV3 artifact
# uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
# with:
# name: dist-opera-MV3-${{ env._BUILD_NUMBER }}.zip
# path: browser-source/apps/browser/dist/dist-opera-mv3.zip
# if-no-files-found: error
- name: Upload Chrome artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
with:
name: dist-chrome-${{ env._BUILD_NUMBER }}.zip
path: browser-source/apps/browser/dist/dist-chrome.zip
if-no-files-found: error
# - name: Upload Chrome MV3 artifact
# uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
# with:
# name: dist-chrome-MV3-${{ env._BUILD_NUMBER }}.zip
# path: browser-source/apps/browser/dist/dist-chrome-mv3.zip
# if-no-files-found: error
- name: Upload Firefox artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
with:
name: dist-firefox-${{ env._BUILD_NUMBER }}.zip
path: browser-source/apps/browser/dist/dist-firefox.zip
if-no-files-found: error
- name: Upload Edge artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
with:
name: dist-edge-${{ env._BUILD_NUMBER }}.zip
path: browser-source/apps/browser/dist/dist-edge.zip
if-no-files-found: error
# - name: Upload Edge MV3 artifact
# uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
# with:
# name: dist-edge-MV3-${{ env._BUILD_NUMBER }}.zip
# path: browser-source/apps/browser/dist/dist-edge-mv3.zip
# if-no-files-found: error
- name: Upload browser source
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: browser-source-${{ env._BUILD_NUMBER }}.zip
path: browser-source.zip
if-no-files-found: error
- name: Upload coverage artifact
if: false
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
- name: NPM setup
run: npm ci
working-directory: browser-source/
- name: Download SDK Artifacts
if: ${{ inputs.sdk_branch != '' }}
uses: bitwarden/gh-actions/download-artifacts@main
with:
name: coverage-${{ env._BUILD_NUMBER }}.zip
path: browser-source/apps/browser/coverage/coverage-${{ env._BUILD_NUMBER }}.zip
github_token: ${{secrets.GITHUB_TOKEN}}
workflow: build-wasm-internal.yml
workflow_conclusion: success
branch: ${{ inputs.sdk_branch }}
artifacts: sdk-internal
repo: bitwarden/sdk-internal
path: sdk-internal
if_no_artifact_found: fail
- name: Override SDK
if: ${{ inputs.sdk_branch != '' }}
working-directory: browser-source/
run: |
npm link ../sdk-internal
- name: Build Chrome
run: npm run dist:chrome
working-directory: browser-source/apps/browser
- name: Upload Chrome MV3 artifact
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: dist-chrome-MV3-${{ env._BUILD_NUMBER }}.zip
path: browser-source/apps/browser/dist/dist-chrome.zip
if-no-files-found: error
- name: Build Edge
run: npm run dist:edge
working-directory: browser-source/apps/browser
- name: Upload Edge artifact
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: dist-edge-${{ env._BUILD_NUMBER }}.zip
path: browser-source/apps/browser/dist/dist-edge.zip
if-no-files-found: error
- name: Build Edge (MV3)
run: npm run dist:edge:mv3
working-directory: browser-source/apps/browser
- name: Upload Edge MV3 artifact (DO NOT USE FOR PROD)
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: DO-NOT-USE-FOR-PROD-dist-edge-MV3-${{ env._BUILD_NUMBER }}.zip
path: browser-source/apps/browser/dist/dist-edge.zip
if-no-files-found: error
- name: Build Firefox
run: npm run dist:firefox
working-directory: browser-source/apps/browser
- name: Upload Firefox artifact
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: dist-firefox-${{ env._BUILD_NUMBER }}.zip
path: browser-source/apps/browser/dist/dist-firefox.zip
if-no-files-found: error
- name: Build Firefox (MV3)
run: npm run dist:firefox:mv3
working-directory: browser-source/apps/browser
- name: Upload Firefox MV3 artifact (DO NOT USE FOR PROD)
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: DO-NOT-USE-FOR-PROD-dist-firefox-MV3-${{ env._BUILD_NUMBER }}.zip
path: browser-source/apps/browser/dist/dist-firefox.zip
if-no-files-found: error
- name: Build Opera
run: npm run dist:opera
working-directory: browser-source/apps/browser
- name: Upload Opera artifact
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: dist-opera-${{ env._BUILD_NUMBER }}.zip
path: browser-source/apps/browser/dist/dist-opera.zip
if-no-files-found: error
- name: Build Opera (MV3)
run: npm run dist:opera:mv3
working-directory: browser-source/apps/browser
- name: Upload Opera MV3 artifact (DO NOT USE FOR PROD)
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: DO-NOT-USE-FOR-PROD-dist-opera-MV3-${{ env._BUILD_NUMBER }}.zip
path: browser-source/apps/browser/dist/dist-opera.zip
if-no-files-found: error
build-safari:
name: Build Safari
runs-on: macos-11
runs-on: macos-13
needs:
- setup
- locales-test
env:
_BUILD_NUMBER: ${{ needs.setup.outputs.adj_build_number }}
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Set up Node
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
node-version: '18'
node-version: ${{ env._NODE_VERSION }}
- name: Print environment
run: |
node --version
npm --version
- name: Decrypt secrets
- name: Login to Azure
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Download Provisioning Profiles secrets
env:
DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }}
ACCOUNT_NAME: bitwardenci
CONTAINER_NAME: profiles
run: |
mkdir -p $HOME/secrets
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/bitwarden-desktop-key.p12" \
"$GITHUB_WORKSPACE/.github/secrets/bitwarden-desktop-key.p12.gpg"
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/appstore-app-cert.p12" \
"$GITHUB_WORKSPACE/.github/secrets/appstore-app-cert.p12.gpg"
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/appstore-installer-cert.p12" \
"$GITHUB_WORKSPACE/.github/secrets/appstore-installer-cert.p12.gpg"
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/devid-app-cert.p12" \
"$GITHUB_WORKSPACE/.github/secrets/devid-app-cert.p12.gpg"
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/devid-installer-cert.p12" \
"$GITHUB_WORKSPACE/.github/secrets/devid-installer-cert.p12.gpg"
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/macdev-cert.p12" \
"$GITHUB_WORKSPACE/.github/secrets/macdev-cert.p12.gpg"
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/bitwarden_desktop_appstore.provisionprofile" \
"$GITHUB_WORKSPACE/.github/secrets/bitwarden_desktop_appstore.provisionprofile.gpg"
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
--name bitwarden_desktop_appstore.provisionprofile \
--file $HOME/secrets/bitwarden_desktop_appstore.provisionprofile \
--output none
- name: Get certificates
run: |
mkdir -p $HOME/certificates
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/bitwarden-desktop-key |
jq -r .value | base64 -d > $HOME/certificates/bitwarden-desktop-key.p12
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-app-cert |
jq -r .value | base64 -d > $HOME/certificates/appstore-app-cert.p12
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-installer-cert |
jq -r .value | base64 -d > $HOME/certificates/appstore-installer-cert.p12
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-app-cert |
jq -r .value | base64 -d > $HOME/certificates/devid-app-cert.p12
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-installer-cert |
jq -r .value | base64 -d > $HOME/certificates/devid-installer-cert.p12
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/macdev-cert |
jq -r .value | base64 -d > $HOME/certificates/macdev-cert.p12
- name: Set up keychain
env:
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
DESKTOP_KEY_PASSWORD: ${{ secrets.DESKTOP_KEY_PASSWORD }}
DEVID_CERT_PASSWORD: ${{ secrets.DEVID_CERT_PASSWORD }}
APPSTORE_CERT_PASSWORD: ${{ secrets.APPSTORE_CERT_PASSWORD }}
MACDEV_CERT_PASSWORD: ${{ secrets.MACDEV_CERT_PASSWORD }}
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
run: |
security create-keychain -p $KEYCHAIN_PASSWORD build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p $KEYCHAIN_PASSWORD build.keychain
security set-keychain-settings -lut 1200 build.keychain
security import "$HOME/secrets/bitwarden-desktop-key.p12" -k build.keychain -P $DESKTOP_KEY_PASSWORD \
security import "$HOME/certificates/bitwarden-desktop-key.p12" -k build.keychain -P "" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import "$HOME/secrets/devid-app-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \
security import "$HOME/certificates/devid-app-cert.p12" -k build.keychain -P "" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import "$HOME/secrets/devid-installer-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \
security import "$HOME/certificates/devid-installer-cert.p12" -k build.keychain -P "" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import "$HOME/secrets/appstore-app-cert.p12" -k build.keychain -P $APPSTORE_CERT_PASSWORD \
security import "$HOME/certificates/appstore-app-cert.p12" -k build.keychain -P "" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import "$HOME/secrets/appstore-installer-cert.p12" -k build.keychain -P $APPSTORE_CERT_PASSWORD \
security import "$HOME/certificates/appstore-installer-cert.p12" -k build.keychain -P "" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import "$HOME/secrets/macdev-cert.p12" -k build.keychain -P $MACDEV_CERT_PASSWORD \
security import "$HOME/certificates/macdev-cert.p12" -k build.keychain -P "" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $KEYCHAIN_PASSWORD build.keychain
- name: NPM setup
run: npm ci
working-directory: ./
- name: Download SDK Artifacts
if: ${{ inputs.sdk_branch != '' }}
uses: bitwarden/gh-actions/download-artifacts@main
with:
github_token: ${{secrets.GITHUB_TOKEN}}
workflow: build-wasm-internal.yml
workflow_conclusion: success
branch: ${{ inputs.sdk_branch }}
artifacts: sdk-internal
repo: bitwarden/sdk-internal
path: ../sdk-internal
if_no_artifact_found: fail
- name: Override SDK
if: ${{ inputs.sdk_branch != '' }}
working-directory: ./
run: |
npm link ../sdk-internal
- name: Build Safari extension
run: npm run dist:safari
working-directory: apps/browser
@@ -337,7 +405,7 @@ jobs:
ls -la
- name: Upload Safari artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: dist-safari-${{ env._BUILD_NUMBER }}.zip
path: apps/browser/dist/dist-safari.zip
@@ -345,36 +413,38 @@ jobs:
crowdin-push:
name: Crowdin Push
if: github.ref == 'refs/heads/master'
if: github.event_name != 'pull_request_target' && github.ref == 'refs/heads/main'
runs-on: ubuntu-22.04
needs:
- build
- build-safari
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Login to Azure
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "crowdin-api-token"
- name: Upload Sources
uses: crowdin/github-action@ee4ab4ea2feadc0fdc3b200729c7b1c4cf4b38f3 # v1.11.0
uses: crowdin/github-action@30849777a3cba6ee9a09e24e195272b8287a0a5b # v1.20.4
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
CROWDIN_PROJECT_ID: "268134"
with:
config: apps/browser/crowdin.yml
crowdin_branch_name: master
crowdin_branch_name: main
upload_sources: true
upload_translations: false
@@ -383,7 +453,6 @@ jobs:
if: always()
runs-on: ubuntu-22.04
needs:
- cloc
- setup
- locales-test
- build
@@ -391,31 +460,14 @@ jobs:
- crowdin-push
steps:
- name: Check if any job failed
if: ${{ (github.ref == 'refs/heads/master') || (github.ref == 'refs/heads/rc') }}
env:
CLOC_STATUS: ${{ needs.cloc.result }}
SETUP_STATUS: ${{ needs.setup.result }}
LOCALES_TEST_STATUS: ${{ needs.locales-test.result }}
BUILD_STATUS: ${{ needs.build.result }}
SAFARI_BUILD_STATUS: ${{ needs.build-safari.result }}
CROWDIN_PUSH_STATUS: ${{ needs.crowdin-push.result }}
run: |
if [ "$CLOC_STATUS" = "failure" ]; then
exit 1
elif [ "$SETUP_STATUS" = "failure" ]; then
exit 1
elif [ "$LOCALES_TEST_STATUS" = "failure" ]; then
exit 1
elif [ "$BUILD_STATUS" = "failure" ]; then
exit 1
elif [ "$SAFARI_BUILD_STATUS" = "failure" ]; then
exit 1
elif [ "$CROWDIN_PUSH_STATUS" = "failure" ]; then
exit 1
fi
if: |
github.event_name != 'pull_request_target'
&& (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc-browser')
&& contains(needs.*.result, 'failure')
run: exit 1
- name: Login to Azure - Prod Subscription
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
if: failure()
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
@@ -423,13 +475,13 @@ jobs:
- name: Retrieve secrets
id: retrieve-secrets
if: failure()
uses: bitwarden/gh-actions/get-keyvault-secrets@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "devops-alerts-slack-webhook-url"
- name: Notify Slack on failure
uses: act10ns/slack@ed1309ab9862e57e9e583e51c7889486b9a00b0f # v2.0.0
uses: act10ns/slack@44541246747a30eb3102d87f7a4cc5471b0ffb7d # v2.1.0
if: failure()
env:
SLACK_WEBHOOK_URL: ${{ steps.retrieve-secrets.outputs.devops-alerts-slack-webhook-url }}

View File

@@ -1,8 +1,8 @@
---
name: Build CLI
on:
pull_request:
pull_request_target:
types: [opened, synchronize]
branches-ignore:
- 'l10n_master'
- 'cf-pages'
@@ -13,9 +13,10 @@ on:
- '!*.md'
- '!*.txt'
- '.github/workflows/build-cli.yml'
- 'bitwarden_license/bit-cli/**'
push:
branches:
- 'master'
- 'main'
- 'rc'
- 'hotfix-rc-cli'
paths:
@@ -25,61 +26,78 @@ on:
- '!*.md'
- '!*.txt'
- '.github/workflows/build-cli.yml'
- 'bitwarden_license/bit-cli/**'
workflow_dispatch:
inputs: {}
inputs:
sdk_branch:
description: "Custom SDK branch"
required: false
type: string
defaults:
run:
working-directory: apps/cli
jobs:
cloc:
name: CLOC
runs-on: ubuntu-22.04
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Set up cloc
run: |
sudo apt update
sudo apt -y install cloc
- name: Print lines of code
run: cloc --include-lang TypeScript,JavaScript --vcs git
check-run:
name: Check PR run
uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main
setup:
name: Setup
runs-on: ubuntu-22.04
needs:
- check-run
outputs:
package_version: ${{ steps.retrieve-version.outputs.package_version }}
package_version: ${{ steps.retrieve-package-version.outputs.package_version }}
node_version: ${{ steps.retrieve-node-version.outputs.node_version }}
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Get Package Version
id: retrieve-version
id: retrieve-package-version
run: |
PKG_VERSION=$(jq -r .version package.json)
echo "package_version=$PKG_VERSION" >> $GITHUB_OUTPUT
- name: Get Node Version
id: retrieve-node-version
working-directory: ./
run: |
NODE_NVMRC=$(cat .nvmrc)
NODE_VERSION=${NODE_NVMRC/v/''}
echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT
cli:
name: Build CLI ${{ matrix.os }}
name: CLI ${{ matrix.os.base }} - ${{ matrix.license_type.readable }}
strategy:
matrix:
os: [ubuntu-22.04, macos-11]
runs-on: ${{ matrix.os }}
os:
[
{ base: "linux", distro: "ubuntu-22.04" },
{ base: "mac", distro: "macos-13" }
]
license_type:
[
{ build_prefix: "oss", artifact_prefix: "-oss", readable: "open source license" },
{ build_prefix: "bit", artifact_prefix: "", readable: "commercial license" }
]
runs-on: ${{ matrix.os.distro }}
needs:
- setup
env:
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
_WIN_PKG_FETCH_VERSION: 18.5.0
_WIN_PKG_VERSION: 3.4
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
_WIN_PKG_FETCH_VERSION: 20.11.1
_WIN_PKG_VERSION: 3.5
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Setup Unix Vars
run: |
@@ -88,32 +106,47 @@ jobs:
awk '{print tolower($0)}')" >> $GITHUB_ENV
- name: Set up Node
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
node-version: '18'
- name: Install node-gyp
run: |
npm install -g node-gyp
node-gyp install $(node -v)
node-version: ${{ env._NODE_VERSION }}
- name: Install
run: npm ci
working-directory: ./
- name: Download SDK Artifacts
if: ${{ inputs.sdk_branch != '' }}
uses: bitwarden/gh-actions/download-artifacts@main
with:
github_token: ${{secrets.GITHUB_TOKEN}}
workflow: build-wasm-internal.yml
workflow_conclusion: success
branch: ${{ inputs.sdk_branch }}
artifacts: sdk-internal
repo: bitwarden/sdk-internal
path: ../sdk-internal
if_no_artifact_found: fail
- name: Override SDK
if: ${{ inputs.sdk_branch != '' }}
working-directory: ./
run: |
ls -l ../
npm link ../sdk-internal
- name: Build & Package Unix
run: npm run dist:${{ env.SHORT_RUNNER_OS }} --quiet
run: npm run dist:${{ matrix.license_type.build_prefix }}:${{ env.SHORT_RUNNER_OS }} --quiet
- name: Zip Unix
run: |
cd ./dist/${{ env.LOWER_RUNNER_OS }}
zip ../bw-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip ./bw
cd ./dist/${{ matrix.license_type.build_prefix }}/${{ env.LOWER_RUNNER_OS }}
zip ../../bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip ./bw
- name: Version Test
run: |
unzip "./dist/bw-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip" -d "./test"
unzip "./dist/bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip" -d "./test"
testVersion=$(./test/bw -v)
echo "version: $_PACKAGE_VERSION"
echo "testVersion: $testVersion"
@@ -125,35 +158,46 @@ jobs:
- name: Create checksums Unix
run: |
cd ./dist
shasum -a 256 bw-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip \
| awk '{split($0, a); print a[1]}' > bw-${{ env.LOWER_RUNNER_OS }}-sha256-${{ env._PACKAGE_VERSION }}.txt
shasum -a 256 bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip \
| awk '{split($0, a); print a[1]}' > bw${{
matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-sha256-${{ env._PACKAGE_VERSION }}.txt
- name: Upload unix zip asset
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: bw-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip
path: apps/cli/dist/bw-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip
name: bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip
path: apps/cli/dist/bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip
if-no-files-found: error
- name: Upload unix checksum asset
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: bw-${{ env.LOWER_RUNNER_OS }}-sha256-${{ env._PACKAGE_VERSION }}.txt
path: apps/cli/dist/bw-${{ env.LOWER_RUNNER_OS }}-sha256-${{ env._PACKAGE_VERSION }}.txt
name: bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-sha256-${{ env._PACKAGE_VERSION }}.txt
path: apps/cli/dist/bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-sha256-${{ env._PACKAGE_VERSION }}.txt
if-no-files-found: error
cli-windows:
name: Build CLI Windows
runs-on: windows-2019
name: Windows - ${{ matrix.license_type.readable }}
strategy:
matrix:
license_type:
[
{ build_prefix: "oss", artifact_prefix: "-oss", readable: "open source license" },
{ build_prefix: "bit", artifact_prefix: "", readable: "commercial license" }
]
runs-on: windows-2022
needs:
- setup
env:
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
_WIN_PKG_FETCH_VERSION: 18.5.0
_WIN_PKG_VERSION: 3.4
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
_WIN_PKG_FETCH_VERSION: 20.11.1
_WIN_PKG_VERSION: 3.5
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Setup Windows builder
run: |
@@ -162,22 +206,17 @@ jobs:
choco install nasm --no-progress
- name: Set up Node
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
node-version: '18'
- name: Install node-gyp
run: |
npm install -g node-gyp
node-gyp install $(node -v)
node-version: ${{ env._NODE_VERSION }}
- name: Get pkg-fetch
shell: pwsh
run: |
cd $HOME
$fetchedUrl = "https://github.com/vercel/pkg-fetch/releases/download/v$env:_WIN_PKG_VERSION/node-v$env:_WIN_PKG_FETCH_VERSION-win-x64"
$fetchedUrl = "https://github.com/yao-pkg/pkg-fetch/releases/download/v$env:_WIN_PKG_VERSION/node-v$env:_WIN_PKG_FETCH_VERSION-win-x64"
New-Item -ItemType directory -Path .\.pkg-cache
New-Item -ItemType directory -Path .\.pkg-cache\v$env:_WIN_PKG_VERSION
Invoke-RestMethod -Uri $fetchedUrl `
@@ -232,26 +271,47 @@ jobs:
run: npm ci
working-directory: ./
- name: Download SDK Artifacts
if: ${{ inputs.sdk_branch != '' }}
uses: bitwarden/gh-actions/download-artifacts@main
with:
github_token: ${{secrets.GITHUB_TOKEN}}
workflow: build-wasm-internal.yml
workflow_conclusion: success
branch: ${{ inputs.sdk_branch }}
artifacts: sdk-internal
repo: bitwarden/sdk-internal
path: ../sdk-internal
if_no_artifact_found: fail
- name: Override SDK
if: ${{ inputs.sdk_branch != '' }}
working-directory: ./
run: |
ls -l ../
npm link ../sdk-internal
- name: Build & Package Windows
run: npm run dist:win --quiet
run: npm run dist:${{ matrix.license_type.build_prefix }}:win --quiet
- name: Package Chocolatey
shell: pwsh
if: ${{ matrix.license_type.build_prefix == 'bit' }}
run: |
Copy-Item -Path stores/chocolatey -Destination dist/chocolatey -Recurse
Copy-Item dist/windows/bw.exe -Destination dist/chocolatey/tools
Copy-Item dist/${{ matrix.license_type.build_prefix }}/windows/bw.exe -Destination dist/chocolatey/tools
Copy-Item ${{ github.workspace }}/LICENSE.txt -Destination dist/chocolatey/tools
choco pack dist/chocolatey/bitwarden-cli.nuspec --version ${{ env._PACKAGE_VERSION }} --out dist/chocolatey
- name: Zip Windows
shell: cmd
run: 7z a ./dist/bw-windows-%_PACKAGE_VERSION%.zip ./dist/windows/bw.exe
run: 7z a ./dist/bw${{ matrix.license_type.artifact_prefix}}-windows-%_PACKAGE_VERSION%.zip ./dist/${{ matrix.license_type.build_prefix }}/windows/bw.exe
- name: Version Test
run: |
dir ./dist/
Expand-Archive -Path "./dist/bw-windows-${env:_PACKAGE_VERSION}.zip" -DestinationPath "./test/windows"
$testVersion = Invoke-Expression '& ./test/windows/bw.exe -v'
Expand-Archive -Path "./dist/bw${{ matrix.license_type.artifact_prefix }}-windows-${env:_PACKAGE_VERSION}.zip" -DestinationPath "./test/${{ matrix.license_type.build_prefix }}/windows"
$testVersion = Invoke-Expression '& ./test/${{ matrix.license_type.build_prefix }}/windows/bw.exe -v'
echo "version: $env:_PACKAGE_VERSION"
echo "testVersion: $testVersion"
if($testVersion -ne $env:_PACKAGE_VERSION) {
@@ -260,46 +320,56 @@ jobs:
- name: Create checksums Windows
run: |
checksum -f="./dist/bw-windows-${env:_PACKAGE_VERSION}.zip" `
-t sha256 | Out-File -Encoding ASCII ./dist/bw-windows-sha256-${env:_PACKAGE_VERSION}.txt
checksum -f="./dist/bw${{ matrix.license_type.artifact_prefix }}-windows-${env:_PACKAGE_VERSION}.zip" `
-t sha256 | Out-File -Encoding ASCII ./dist/bw${{ matrix.license_type.artifact_prefix }}-windows-sha256-${env:_PACKAGE_VERSION}.txt
- name: Upload windows zip asset
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: bw-windows-${{ env._PACKAGE_VERSION }}.zip
path: apps/cli/dist/bw-windows-${{ env._PACKAGE_VERSION }}.zip
name: bw${{ matrix.license_type.artifact_prefix }}-windows-${{ env._PACKAGE_VERSION }}.zip
path: apps/cli/dist/bw${{ matrix.license_type.artifact_prefix }}-windows-${{ env._PACKAGE_VERSION }}.zip
if-no-files-found: error
- name: Upload windows checksum asset
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: bw-windows-sha256-${{ env._PACKAGE_VERSION }}.txt
path: apps/cli/dist/bw-windows-sha256-${{ env._PACKAGE_VERSION }}.txt
name: bw${{ matrix.license_type.artifact_prefix }}-windows-sha256-${{ env._PACKAGE_VERSION }}.txt
path: apps/cli/dist/bw${{ matrix.license_type.artifact_prefix }}-windows-sha256-${{ env._PACKAGE_VERSION }}.txt
if-no-files-found: error
- name: Upload Chocolatey asset
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
if: matrix.license_type.build_prefix == 'bit'
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: bitwarden-cli.${{ env._PACKAGE_VERSION }}.nupkg
path: apps/cli/dist/chocolatey/bitwarden-cli.${{ env._PACKAGE_VERSION }}.nupkg
if-no-files-found: error
- name: Zip NPM Build Artifact
run: Get-ChildItem -Path .\build | Compress-Archive -DestinationPath .\bitwarden-cli-${{ env._PACKAGE_VERSION }}-npm-build.zip
- name: Upload NPM Build Directory asset
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
if: matrix.license_type.build_prefix == 'bit'
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: bitwarden-cli-${{ env._PACKAGE_VERSION }}-npm-build.zip
path: apps/cli/build
path: apps/cli/bitwarden-cli-${{ env._PACKAGE_VERSION }}-npm-build.zip
if-no-files-found: error
snap:
name: Build Snap
# Note, before updating the ubuntu version of the workflow, ensure the snap base image
# is equal or greater than the new version. Otherwise there might be GLIBC version issues.
# The snap base for CLI is defined in `apps/cli/stores/snap/snapcraft.yaml`
runs-on: ubuntu-22.04
needs: [setup, cli]
env:
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Print environment
run: |
@@ -309,7 +379,7 @@ jobs:
echo "BW Package Version: $_PACKAGE_VERSION"
- name: Get bw linux cli
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: bw-linux-${{ env._PACKAGE_VERSION }}.zip
path: apps/cli/dist/snap
@@ -322,7 +392,7 @@ jobs:
ls -alth
- name: Build snap
uses: snapcore/action-build@2ee46bc29d163c9c836f2820cc46b39664bf0de2 # v1.1.3
uses: snapcore/action-build@3bdaa03e1ba6bf59a65f84a751d943d549a54e79 # v1.3.0
with:
path: apps/cli/dist/snap
@@ -351,14 +421,14 @@ jobs:
run: sudo snap remove bw
- name: Upload snap asset
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: bw_${{ env._PACKAGE_VERSION }}_amd64.snap
path: apps/cli/dist/snap/bw_${{ env._PACKAGE_VERSION }}_amd64.snap
if-no-files-found: error
- name: Upload snap checksum asset
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: bw-snap-sha256-${{ env._PACKAGE_VERSION }}.txt
path: apps/cli/dist/snap/bw-snap-sha256-${{ env._PACKAGE_VERSION }}.txt
@@ -370,7 +440,6 @@ jobs:
if: always()
runs-on: ubuntu-22.04
needs:
- cloc
- setup
- cli
- cli-windows
@@ -378,25 +447,14 @@ jobs:
steps:
- name: Check if any job failed
working-directory: ${{ github.workspace }}
if: ${{ (github.ref == 'refs/heads/master') || (github.ref == 'refs/heads/rc') }}
env:
CLOC_STATUS: ${{ needs.cloc.result }}
SETUP_STATUS: ${{ needs.setup.result }}
CLI_STATUS: ${{ needs.cli.result }}
SNAP_STATUS: ${{ needs.snap.result }}
run: |
if [ "$CLOC_STATUS" = "failure" ]; then
exit 1
elif [ "$SETUP_STATUS" = "failure" ]; then
exit 1
elif [ "$CLI_STATUS" = "failure" ]; then
exit 1
elif [ "$SNAP_STATUS" = "failure" ]; then
exit 1
fi
if: |
github.event_name != 'pull_request_target'
&& (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc-cli')
&& contains(needs.*.result, 'failure')
run: exit 1
- name: Login to Azure - Prod Subscription
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
if: failure()
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
@@ -404,13 +462,13 @@ jobs:
- name: Retrieve secrets
id: retrieve-secrets
if: failure()
uses: bitwarden/gh-actions/get-keyvault-secrets@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "devops-alerts-slack-webhook-url"
- name: Notify Slack on failure
uses: act10ns/slack@ed1309ab9862e57e9e583e51c7889486b9a00b0f # v2.0.0
uses: act10ns/slack@44541246747a30eb3102d87f7a4cc5471b0ffb7d # v2.1.0
if: failure()
env:
SLACK_WEBHOOK_URL: ${{ steps.retrieve-secrets.outputs.devops-alerts-slack-webhook-url }}

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,8 @@
---
name: Build Web
on:
pull_request:
pull_request_target:
types: [opened, synchronize]
branches-ignore:
- 'l10n_master'
- 'cf-pages'
@@ -15,7 +15,7 @@ on:
- '.github/workflows/build-web.yml'
push:
branches:
- 'master'
- 'main'
- 'rc'
- 'hotfix-rc-web'
paths:
@@ -25,52 +25,59 @@ on:
- '!*.md'
- '!*.txt'
- '.github/workflows/build-web.yml'
release:
types: [published]
workflow_dispatch:
inputs:
custom_tag_extension:
description: "Custom image tag extension"
required: false
sdk_branch:
description: "Custom SDK branch"
required: false
type: string
env:
_AZ_REGISTRY: bitwardenprod.azurecr.io
jobs:
cloc:
name: CLOC
runs-on: ubuntu-22.04
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Set up cloc
run: |
sudo apt update
sudo apt -y install cloc
- name: Print lines of code
working-directory: apps/web
run: cloc --include-lang TypeScript,JavaScript,HTML,Sass,CSS --vcs git
check-run:
name: Check PR run
uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main
setup:
name: Setup
runs-on: ubuntu-22.04
needs:
- check-run
outputs:
version: ${{ steps.version.outputs.value }}
node_version: ${{ steps.retrieve-node-version.outputs.node_version }}
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Get GitHub sha as version
id: version
run: echo "value=${GITHUB_SHA:0:7}" >> $GITHUB_OUTPUT
- name: Get Node Version
id: retrieve-node-version
run: |
NODE_NVMRC=$(cat .nvmrc)
NODE_VERSION=${NODE_NVMRC/v/''}
echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT
build-artifacts:
name: Build artifacts
runs-on: ubuntu-22.04
needs: setup
needs:
- setup
env:
_VERSION: ${{ needs.setup.outputs.version }}
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
strategy:
matrix:
include:
@@ -82,23 +89,31 @@ jobs:
npm_command: "dist:bit:selfhost"
- name: "cloud-QA"
npm_command: "build:bit:qa"
git_metadata: true
- name: "ee"
npm_command: "build:bit:ee"
git_metadata: true
- name: "cloud-euprd"
npm_command: "build:bit:euprd"
- name: "cloud-euqa"
npm_command: "build:bit:euqa"
git_metadata: true
- name: "cloud-usdev"
npm_command: "build:bit:usdev"
git_metadata: true
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Set up Node
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
node-version: "16"
node-version: ${{ env._NODE_VERSION }}
- name: Print environment
run: |
@@ -113,9 +128,29 @@ jobs:
- name: Install dependencies
run: npm ci
- name: Setup QA metadata
- name: Download SDK Artifacts
if: ${{ inputs.sdk_branch != '' }}
uses: bitwarden/gh-actions/download-artifacts@main
with:
github_token: ${{secrets.GITHUB_TOKEN}}
workflow: build-wasm-internal.yml
workflow_conclusion: success
branch: ${{ inputs.sdk_branch }}
artifacts: sdk-internal
repo: bitwarden/sdk-internal
path: ../sdk-internal
if_no_artifact_found: fail
- name: Override SDK
if: ${{ inputs.sdk_branch != '' }}
working-directory: ./
run: |
ls -l ../
npm link ../sdk-internal
- name: Add Git metadata to build version
working-directory: apps/web
if: matrix.name == 'cloud-QA'
if: matrix.git_metadata
run: |
VERSION=$( jq -r ".version" package.json)
jq --arg version "$VERSION+${GITHUB_SHA:0:7}" '.version = $version' package.json > package.json.tmp
@@ -130,7 +165,7 @@ jobs:
run: zip -r web-${{ env._VERSION }}-${{ matrix.name }}.zip build
- name: Upload ${{ matrix.name }} artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: web-${{ env._VERSION }}-${{ matrix.name }}.zip
path: apps/web/web-${{ env._VERSION }}-${{ matrix.name }}.zip
@@ -156,12 +191,14 @@ jobs:
env:
_VERSION: ${{ needs.setup.outputs.version }}
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Check Branch to Publish
env:
PUBLISH_BRANCHES: "master,rc,hotfix-rc-web"
PUBLISH_BRANCHES: "main,rc,hotfix-rc-web"
id: publish-branch-check
run: |
IFS="," read -a publish_branches <<< $PUBLISH_BRANCHES
@@ -174,7 +211,7 @@ jobs:
########## ACRs ##########
- name: Login to Prod Azure
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
@@ -182,19 +219,19 @@ jobs:
run: az acr login -n bitwardenprod
- name: Login to Azure - CI Subscription
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve github PAT secrets
id: retrieve-secret-pat
uses: bitwarden/gh-actions/get-keyvault-secrets@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "github-pat-bitwarden-devops-bot-repo-scope"
- name: Download ${{ matrix.artifact_name }} artifact
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: web-${{ env._VERSION }}-${{ matrix.artifact_name }}.zip
path: apps/web
@@ -203,13 +240,13 @@ jobs:
- name: Generate Docker image tag
id: tag
run: |
if [[ $(grep "pull" <<< "${GITHUB_REF}") ]]; then
if [[ "${GITHUB_EVENT_NAME}" == "pull_request_target" ]]; then
IMAGE_TAG=$(echo "${GITHUB_HEAD_REF}" | sed "s#/#-#g")
else
IMAGE_TAG=$(echo "${GITHUB_REF:11}" | sed "s#/#-#g")
IMAGE_TAG=$(echo "${GITHUB_REF_NAME}" | sed "s#/#-#g")
fi
if [[ "$IMAGE_TAG" == "master" ]]; then
if [[ "$IMAGE_TAG" == "main" ]]; then
IMAGE_TAG=dev
fi
@@ -234,7 +271,7 @@ jobs:
run: echo "name=$_AZ_REGISTRY/${PROJECT_NAME}:${IMAGE_TAG}" >> $GITHUB_OUTPUT
- name: Build Docker image
uses: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825 # v4.1.1
uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6.9.0
with:
context: apps/web
file: apps/web/Dockerfile
@@ -250,74 +287,95 @@ jobs:
crowdin-push:
name: Crowdin Push
if: github.ref == 'refs/heads/master'
needs: build-artifacts
if: github.event_name != 'pull_request_target' && github.ref == 'refs/heads/main'
needs:
- build-artifacts
runs-on: ubuntu-22.04
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Login to Azure
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "crowdin-api-token"
- name: Upload Sources
uses: crowdin/github-action@ee4ab4ea2feadc0fdc3b200729c7b1c4cf4b38f3 # v1.11.0
uses: crowdin/github-action@30849777a3cba6ee9a09e24e195272b8287a0a5b # v1.20.4
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
CROWDIN_PROJECT_ID: "308189"
with:
config: apps/web/crowdin.yml
crowdin_branch_name: master
crowdin_branch_name: main
upload_sources: true
upload_translations: false
trigger-web-vault-deploy:
name: Trigger web vault deploy
if: github.event_name != 'pull_request_target' && github.ref == 'refs/heads/main'
runs-on: ubuntu-22.04
needs:
- build-artifacts
steps:
- name: Login to Azure - CI Subscription
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve github PAT secrets
id: retrieve-secret-pat
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "github-pat-bitwarden-devops-bot-repo-scope"
- name: Trigger web vault deploy using GitHub Run ID
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
github-token: ${{ steps.retrieve-secret-pat.outputs.github-pat-bitwarden-devops-bot-repo-scope }}
script: |
await github.rest.actions.createWorkflowDispatch({
owner: 'bitwarden',
repo: 'clients',
workflow_id: 'deploy-web.yml',
ref: 'main',
inputs: {
'environment': 'USDEV',
'build-web-run-id': '${{ github.run_id }}'
}
})
check-failures:
name: Check for failures
if: always()
runs-on: ubuntu-22.04
needs:
- cloc
- setup
- build-artifacts
- build-containers
- crowdin-push
- trigger-web-vault-deploy
steps:
- name: Check if any job failed
if: ${{ (github.ref == 'refs/heads/master') || (github.ref == 'refs/heads/rc') }}
env:
CLOC_STATUS: ${{ needs.cloc.result }}
SETUP_STATUS: ${{ needs.setup.result }}
ARTIFACT_STATUS: ${{ needs.build-artifacts.result }}
BUILD_CONTAINERS_STATUS: ${{ needs.build-containers.result }}
CROWDIN_PUSH_STATUS: ${{ needs.crowdin-push.result }}
run: |
if [ "$CLOC_STATUS" = "failure" ]; then
exit 1
elif [ "$SETUP_STATUS" = "failure" ]; then
exit 1
elif [ "$ARTIFACT_STATUS" = "failure" ]; then
exit 1
elif [ "$BUILD_SELFHOST_STATUS" = "failure" ]; then
exit 1
elif [ "$BUILD_CONTAINERS_STATUS" = "failure" ]; then
exit 1
elif [ "$CROWDIN_PUSH_STATUS" = "failure" ]; then
exit 1
fi
if: |
github.event_name != 'pull_request_target'
&& (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc-web')
&& contains(needs.*.result, 'failure')
run: exit 1
- name: Login to Azure - Prod Subscription
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
if: failure()
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
@@ -325,13 +383,13 @@ jobs:
- name: Retrieve secrets
id: retrieve-secrets
if: failure()
uses: bitwarden/gh-actions/get-keyvault-secrets@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "devops-alerts-slack-webhook-url"
- name: Notify Slack on failure
uses: act10ns/slack@ed1309ab9862e57e9e583e51c7889486b9a00b0f # v2.0.0
uses: act10ns/slack@44541246747a30eb3102d87f7a4cc5471b0ffb7d # v2.1.0
if: failure()
env:
SLACK_WEBHOOK_URL: ${{ steps.retrieve-secrets.outputs.devops-alerts-slack-webhook-url }}

View File

@@ -1,43 +1,62 @@
---
name: Chromatic
on:
push:
paths-ignore:
- '.github/workflows/**'
branches:
- "main"
- "rc"
- "hotfix-rc"
pull_request_target:
types: [opened, synchronize]
jobs:
check-run:
name: Check PR run
uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main
chromatic:
name: Chromatic
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
needs: check-run
permissions:
contents: read
pull-requests: write
steps:
- name: Set up Node
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
with:
node-version: "16"
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- name: Cache npm
- name: Get Node version
id: retrieve-node-version
run: |
NODE_NVMRC=$(cat .nvmrc)
NODE_VERSION=${NODE_NVMRC/v/''}
echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT
- name: Set up Node
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: ${{ steps.retrieve-node-version.outputs.node_version }}
- name: Cache NPM
id: npm-cache
uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1
uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2
with:
path: "~/.npm"
key: ${{ runner.os }}-npm-chromatic-${{ hashFiles('**/package-lock.json') }}
- name: Install Node dependencies
run: npm ci
# Manual build the storybook to resolve a chromatic/storybook bug related to TurboSnap
# Manually build the Storybook to resolve a bug related to TurboSnap
- name: Build Storybook
run: npm run build-storybook:ci
- name: Publish to Chromatic
uses: chromaui/action@a45a922b9a7522a4cbb59a7bb7b288a768968924
uses: chromaui/action@dd2eecb9bef44f54774581f4163b0327fd8cf607 # v11.16.3
with:
token: ${{ secrets.GITHUB_TOKEN }}
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}

View File

@@ -1,4 +1,3 @@
---
name: Crowdin Sync
on:
@@ -10,7 +9,7 @@ on:
jobs:
crowdin-sync:
name: Autosync
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
@@ -23,29 +22,36 @@ jobs:
crowdin_project_id: "308189"
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Login to Azure
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "crowdin-api-token, github-gpg-private-key, github-gpg-private-key-passphrase"
- name: Generate GH App token
uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0
id: app-token
with:
app-id: ${{ secrets.BW_GHAPP_ID }}
private-key: ${{ secrets.BW_GHAPP_KEY }}
- name: Download translations
uses: bitwarden/gh-actions/crowdin@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
uses: bitwarden/gh-actions/crowdin@main
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
CROWDIN_PROJECT_ID: ${{ matrix.crowdin_project_id }}
with:
config: crowdin.yml
crowdin_branch_name: master
crowdin_branch_name: main
upload_sources: false
upload_translations: false
download_translations: true
@@ -59,4 +65,3 @@ jobs:
working_directory: apps/${{ matrix.app_name }}
gpg_private_key: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key }}
gpg_passphrase: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key-passphrase }}

View File

@@ -1,60 +0,0 @@
---
name: Deploy Web to EU-PRD Cloud
on:
workflow_dispatch:
inputs:
tag:
description: "Branch name to deploy (examples: 'master', 'feature/sm')"
required: true
type: string
default: master
jobs:
azure-deploy:
name: Deploy to Azure
runs-on: ubuntu-22.04
env:
_WEB_ARTIFACT: "web-*-cloud-euprd.zip"
steps:
- name: Login to Azure - EU Subscription
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
with:
creds: ${{ secrets.AZURE_KV_EU_PRD_SERVICE_PRINCIPAL }}
- name: Retrieve Storage Account connection string
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
keyvault: webvault-westeurope-prod
secrets: "sa-bitwarden-web-vault-dev-key-temp"
- name: Download latest cloud asset
uses: bitwarden/gh-actions/download-artifacts@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
workflow: build-web.yml
path: apps/web
workflow_conclusion: success
branch: ${{ github.event.inputs.tag }}
artifacts: ${{ env._WEB_ARTIFACT }}
- name: Unzip build asset
working-directory: apps/web
run: unzip ${{ env._WEB_ARTIFACT }}
- name: Empty container in Storage Account
run: |
az storage blob delete-batch \
--source '$web' \
--pattern '*' \
--connection-string "${{ steps.retrieve-secrets.outputs.sa-bitwarden-web-vault-dev-key-temp }}"
- name: Deploy to Azure Storage Account
working-directory: apps/web
run: |
az storage blob upload-batch \
--source "./build" \
--destination '$web' \
--connection-string "${{ steps.retrieve-secrets.outputs.sa-bitwarden-web-vault-dev-key-temp }}" \
--overwrite \
--no-progress

View File

@@ -1,60 +0,0 @@
---
name: Deploy Web to EU-QA Cloud
on:
workflow_dispatch:
inputs:
tag:
description: "Branch name to deploy (examples: 'master', 'feature/sm')"
required: true
type: string
default: master
jobs:
azure-deploy:
name: Deploy to Azure
runs-on: ubuntu-22.04
env:
_WEB_ARTIFACT: "web-*-cloud-euqa.zip"
steps:
- name: Login to Azure - EU Subscription
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
with:
creds: ${{ secrets.AZURE_KV_EU_QA_SERVICE_PRINCIPAL }}
- name: Retrieve Storage Account connection string
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
keyvault: webvaulteu-westeurope-qa
secrets: "sa-bitwarden-web-vault-dev-key-temp"
- name: Download latest cloud asset
uses: bitwarden/gh-actions/download-artifacts@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
workflow: build-web.yml
path: apps/web
workflow_conclusion: success
branch: ${{ github.event.inputs.tag }}
artifacts: ${{ env._WEB_ARTIFACT }}
- name: Unzip build asset
working-directory: apps/web
run: unzip ${{ env._WEB_ARTIFACT }}
- name: Empty container in Storage Account
run: |
az storage blob delete-batch \
--source '$web' \
--pattern '*' \
--connection-string "${{ steps.retrieve-secrets.outputs.sa-bitwarden-web-vault-dev-key-temp }}"
- name: Deploy to Azure Storage Account
working-directory: apps/web
run: |
az storage blob upload-batch \
--source "./build" \
--destination '$web' \
--connection-string "${{ steps.retrieve-secrets.outputs.sa-bitwarden-web-vault-dev-key-temp }}" \
--overwrite \
--no-progress

View File

@@ -1,128 +0,0 @@
---
name: Deploy Web - Non-Prod
run-name: Deploy Web ${{ inputs.environment }}
on:
workflow_dispatch:
inputs:
environment:
description: 'Environment'
default: 'QA'
type: choice
options:
- QA
workflow_call:
inputs:
environment:
description: 'Environment'
default: 'QA'
type: string
jobs:
setup:
name: Setup
runs-on: ubuntu-20.04
outputs:
environment: ${{ steps.config.outputs.environment }}
environment-url: ${{ steps.config.outputs.environment-url }}
environment-name: ${{ steps.config.outputs.environment-name }}
environment-branch: ${{ steps.config.outputs.environment-branch }}
environment-artifact: ${{ steps.config.outputs.environment-artifact }}
steps:
- name: Configure
id: config
run: |
ENV_NAME_LOWER=$(echo "${{ inputs.environment }}" | awk '{print tolower($0)}')
echo "configuring the Web deploy for ${{ inputs.environment }}"
echo "environment=${{ inputs.environment }}" >> $GITHUB_OUTPUT
echo "environment-url=http://vault.$ENV_NAME_LOWER.bitwarden.pw" >> $GITHUB_OUTPUT
echo "environment-name=Web Vault - ${{ inputs.environment }}" >> $GITHUB_OUTPUT
echo "environment-branch=cf-pages-$ENV_NAME_LOWER" >> $GITHUB_OUTPUT
echo "environment-artifact=web-*-cloud-${{ inputs.environment }}.zip" >> $GITHUB_OUTPUT
cfpages-deploy:
name: Deploy Web Vault to ${{ inputs.environment }} CloudFlare Pages branch
needs: setup
runs-on: ubuntu-20.04
env:
_ENVIRONMENT: ${{ needs.setup.outputs.environment }}
_ENVIRONMENT_URL: ${{ needs.setup.outputs.environment-url }}
_ENVIRONMENT_NAME: ${{ needs.setup.outputs.environment-name }}
_ENVIRONMENT_BRANCH: ${{ needs.setup.outputs.environment-branch }}
_ENVIRONMENT_ARTIFACT: ${{ needs.setup.outputs.environment-artifact }}
steps:
- name: Create GitHub deployment
uses: chrnorm/deployment-action@d42cde7132fcec920de534fffc3be83794335c00 # v2.0.5
id: deployment
with:
token: '${{ secrets.GITHUB_TOKEN }}'
initial-status: 'in_progress'
environment-url: ${{ env._ENVIRONMENT_URL }}
environment: ${{ env._ENVIRONMENT_NAME }}
description: 'Deployment from branch ${{ github.ref_name }}'
- name: Checkout Repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Download latest cloud asset
uses: bitwarden/gh-actions/download-artifacts@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
workflow: build-web.yml
path: apps/web
workflow_conclusion: success
branch: ${{ github.ref_name }}
artifacts: ${{ env._ENVIRONMENT_ARTIFACT }}
- name: Unzip cloud asset
working-directory: apps/web
run: unzip ${{ env._ENVIRONMENT_ARTIFACT }}
- name: Checkout Repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
with:
ref: ${{ env._ENVIRONMENT_BRANCH }}
path: deployment
- name: Setup git config
run: |
git config --global user.name "GitHub Action Bot"
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --global url."https://github.com/".insteadOf ssh://git@github.com/
git config --global url."https://".insteadOf ssh://
- name: Deploy CloudFlare Pages
run: |
rm -rf ./*
cp -R ../apps/web/build/* .
working-directory: deployment
- name: Push new ver to ${{ env._ENVIRONMENT_BRANCH }}
run: |
if [ -n "$(git status --porcelain)" ]; then
git add .
git commit -m "Deploy ${{ github.ref_name }} to ${{ env._ENVIRONMENT }} Cloudflare pages"
git push -u origin ${{ env._ENVIRONMENT_BRANCH }}
else
echo "No changes to commit!";
fi
working-directory: deployment
- name: Update deployment status to Success
if: ${{ success() }}
uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1
with:
token: '${{ secrets.GITHUB_TOKEN }}'
environment-url: ${{ env._ENVIRONMENT_URL }}
state: 'success'
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
- name: Update deployment status to Failure
if: ${{ failure() }}
uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1
with:
token: '${{ secrets.GITHUB_TOKEN }}'
environment-url: ${{ env._ENVIRONMENT_URL }}
state: 'failure'
deployment-id: ${{ steps.deployment.outputs.deployment_id }}

434
.github/workflows/deploy-web.yml vendored Normal file
View File

@@ -0,0 +1,434 @@
name: Deploy Web Vault
run-name: Deploy Web Vault to ${{ inputs.environment }} from ${{ inputs.branch-or-tag }}
on:
workflow_dispatch:
inputs:
environment:
description: 'Environment'
default: 'USQA'
type: choice
options:
- USQA
- EUQA
- USPROD
- EUPROD
- USDEV
branch-or-tag:
description: "Branch or Tag name to deploy (examples: 'main', 'feature/sm', 'web-v2023.12.0')"
type: string
default: main
force-delete-destination:
description: "Delete remote files that are not found locally"
type: boolean
default: false
debug:
description: "Debug mode"
type: boolean
default: true
build-web-run-id:
description: "Build-web workflow Run ID to use for artifact download"
type: string
required: false
workflow_call:
inputs:
environment:
description: 'Environment'
default: 'USQA'
type: string
branch-or-tag:
description: "Branch or Tag name to deploy (examples: 'main', 'feature/sm', 'web-v2023.12.0')"
type: string
default: main
force-delete-destination:
description: "Delete remote files that are not found locally"
type: boolean
default: false
debug:
description: "Debug mode"
type: boolean
default: true
build-web-run-id:
description: "Build-web workflow Run ID to use for artifact download"
type: string
required: false
permissions:
deployments: write
jobs:
setup:
name: Setup
runs-on: ubuntu-22.04
outputs:
environment: ${{ steps.config.outputs.environment }}
environment-url: ${{ steps.config.outputs.environment-url }}
environment-name: ${{ steps.config.outputs.environment-name }}
environment-artifact: ${{ steps.config.outputs.environment-artifact }}
azure-login-creds: ${{ steps.config.outputs.azure-login-creds }}
retrieve-secrets-keyvault: ${{ steps.config.outputs.retrieve-secrets-keyvault }}
sync-utility: ${{ steps.config.outputs.sync-utility }}
sync-delete-destination-files: ${{ steps.config.outputs.sync-delete-destination-files }}
slack-channel-name: ${{ steps.config.outputs.slack-channel-name }}
steps:
- name: Configure
id: config
run: |
ENV_NAME_LOWER=$(echo "${{ inputs.environment }}" | awk '{print tolower($0)}')
echo "configuring the Web deploy for ${{ inputs.environment }}"
echo "environment=${{ inputs.environment }}" >> $GITHUB_OUTPUT
case ${{ inputs.environment }} in
"USQA")
echo "azure-login-creds=AZURE_KV_US_QA_SERVICE_PRINCIPAL" >> $GITHUB_OUTPUT
echo "retrieve-secrets-keyvault=bw-webvault-rlktusqa-kv" >> $GITHUB_OUTPUT
echo "environment-artifact=web-*-cloud-QA.zip" >> $GITHUB_OUTPUT
echo "environment-name=Web Vault - US QA Cloud" >> $GITHUB_OUTPUT
echo "environment-url=http://vault.$ENV_NAME_LOWER.bitwarden.pw" >> $GITHUB_OUTPUT
echo "slack-channel-name=alerts-deploy-qa" >> $GITHUB_OUTPUT
;;
"EUQA")
echo "azure-login-creds=AZURE_KV_EU_QA_SERVICE_PRINCIPAL" >> $GITHUB_OUTPUT
echo "retrieve-secrets-keyvault=webvaulteu-westeurope-qa" >> $GITHUB_OUTPUT
echo "environment-artifact=web-*-cloud-euqa.zip" >> $GITHUB_OUTPUT
echo "environment-name=Web Vault - EU QA Cloud" >> $GITHUB_OUTPUT
echo "environment-url=http://vault.$ENV_NAME_LOWER.bitwarden.pw" >> $GITHUB_OUTPUT
echo "slack-channel-name=alerts-deploy-qa" >> $GITHUB_OUTPUT
;;
"USPROD")
echo "azure-login-creds=AZURE_KV_US_PROD_SERVICE_PRINCIPAL" >> $GITHUB_OUTPUT
echo "retrieve-secrets-keyvault=bw-webvault-klrt-kv" >> $GITHUB_OUTPUT
echo "environment-artifact=web-*-cloud-COMMERCIAL.zip" >> $GITHUB_OUTPUT
echo "environment-name=Web Vault - US Production Cloud" >> $GITHUB_OUTPUT
echo "environment-url=http://vault.bitwarden.com" >> $GITHUB_OUTPUT
echo "slack-channel-name=alerts-deploy-prd" >> $GITHUB_OUTPUT
;;
"EUPROD")
echo "azure-login-creds=AZURE_KV_EU_PRD_SERVICE_PRINCIPAL" >> $GITHUB_OUTPUT
echo "retrieve-secrets-keyvault=webvault-westeurope-prod" >> $GITHUB_OUTPUT
echo "environment-artifact=web-*-cloud-euprd.zip" >> $GITHUB_OUTPUT
echo "environment-name=Web Vault - EU Production Cloud" >> $GITHUB_OUTPUT
echo "environment-url=http://vault.bitwarden.eu" >> $GITHUB_OUTPUT
echo "slack-channel-name=alerts-deploy-prd" >> $GITHUB_OUTPUT
;;
"USDEV")
echo "azure-login-creds=AZURE_KV_US_DEV_SERVICE_PRINCIPAL" >> $GITHUB_OUTPUT
echo "retrieve-secrets-keyvault=webvault-eastus-dev" >> $GITHUB_OUTPUT
echo "environment-artifact=web-*-cloud-usdev.zip" >> $GITHUB_OUTPUT
echo "environment-name=Web Vault - US Development Cloud" >> $GITHUB_OUTPUT
echo "environment-url=http://vault.$ENV_NAME_LOWER.bitwarden.pw" >> $GITHUB_OUTPUT
echo "slack-channel-name=alerts-deploy-dev" >> $GITHUB_OUTPUT
;;
esac
# Set the sync utility to use for deployment to the environment (az-sync or azcopy)
echo "sync-utility=azcopy" >> $GITHUB_OUTPUT
- name: Environment Protection
env:
BUILD_WEB_RUN_ID: ${{ inputs.build-web-run-id }}
GH_TOKEN: ${{ github.token }}
run: |
BRANCH_OR_TAG_LOWER=""
if [[ "$BUILD_WEB_RUN_ID" == "" ]]; then
BRANCH_OR_TAG_LOWER=$(echo ${{ inputs.branch-or-tag }} | awk '{print tolower($0)}')
else
BRANCH_OR_TAG_LOWER=$(gh api /repos/bitwarden/clients/actions/runs/$BUILD_WEB_RUN_ID/artifacts --jq '.artifacts[0].workflow_run.head_branch' | awk '{print tolower($0)}')
fi
echo "Branch/Tag: $BRANCH_OR_TAG_LOWER"
PROD_ENV_PATTERN='USPROD|EUPROD'
PROD_ALLOWED_TAGS_PATTERN='web-v[0-9]+\.[0-9]+\.[0-9]+'
QA_ENV_PATTERN='USQA|EUQA'
QA_ALLOWED_TAGS_PATTERN='.*'
DEV_ENV_PATTERN='USDEV'
DEV_ALLOWED_TAGS_PATTERN='main'
if [[ \
${{ inputs.environment }} =~ \.*($PROD_ENV_PATTERN)\.* && \
! "$BRANCH_OR_TAG_LOWER" =~ ^($PROD_ALLOWED_TAGS_PATTERN).* \
]] || [[ \
${{ inputs.environment }} =~ \.*($QA_ENV_PATTERN)\.* && \
! "$BRANCH_OR_TAG_LOWER" =~ ^($QA_ALLOWED_TAGS_PATTERN).* \
]] || [[ \
${{ inputs.environment }} =~ \.*($DEV_ENV_PATTERN)\.* && \
$BRANCH_OR_TAG_LOWER != $DEV_ALLOWED_TAGS_PATTERN \
]]; then
echo "!Deployment blocked!"
echo "Attempting to deploy a tag that is not allowed in ${{ inputs.environment }} environment"
echo
echo "Environment: ${{ inputs.environment }}"
echo "Tag: $BRANCH_OR_TAG_LOWER"
exit 1
else
echo "The input Branch/Tag: '$BRANCH_OR_TAG_LOWER' is allowed to deploy on ${{ inputs.environment }} environment"
fi
approval:
name: Approval for Deployment to ${{ needs.setup.outputs.environment-name }}
needs: setup
runs-on: ubuntu-22.04
environment: ${{ needs.setup.outputs.environment-name }}
steps:
- name: Success Code
run: exit 0
artifact-check:
name: Check if Web artifact is present
runs-on: ubuntu-22.04
needs: setup
env:
_ENVIRONMENT_ARTIFACT: ${{ needs.setup.outputs.environment-artifact }}
outputs:
artifact-build-commit: ${{ steps.set-artifact-commit.outputs.commit }}
steps:
- name: 'Download latest cloud asset using GitHub Run ID: ${{ inputs.build-web-run-id }}'
if: ${{ inputs.build-web-run-id }}
uses: bitwarden/gh-actions/download-artifacts@main
id: download-latest-artifacts-run-id
continue-on-error: true
with:
workflow: build-web.yml
path: apps/web
workflow_conclusion: success
run_id: ${{ inputs.build-web-run-id }}
artifacts: ${{ env._ENVIRONMENT_ARTIFACT }}
- name: 'Download latest cloud asset from branch/tag: ${{ inputs.branch-or-tag }}'
if: ${{ !inputs.build-web-run-id }}
uses: bitwarden/gh-actions/download-artifacts@main
id: download-latest-artifacts
continue-on-error: true
with:
workflow: build-web.yml
path: apps/web
workflow_conclusion: success
branch: ${{ inputs.branch-or-tag }}
artifacts: ${{ env._ENVIRONMENT_ARTIFACT }}
- name: Login to Azure
if: ${{ steps.download-latest-artifacts.outcome == 'failure' }}
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets for Build trigger
if: ${{ steps.download-latest-artifacts.outcome == 'failure' }}
id: retrieve-secret
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "github-pat-bitwarden-devops-bot-repo-scope"
- name: 'Trigger build web for missing branch/tag ${{ inputs.branch-or-tag }}'
if: ${{ steps.download-latest-artifacts.outcome == 'failure' }}
uses: convictional/trigger-workflow-and-wait@f69fa9eedd3c62a599220f4d5745230e237904be # v1.6.5
id: trigger-build-web
with:
owner: bitwarden
repo: clients
github_token: ${{ steps.retrieve-secret.outputs.github-pat-bitwarden-devops-bot-repo-scope }}
workflow_file_name: build-web.yml
ref: ${{ inputs.branch-or-tag }}
wait_interval: 100
- name: Set artifact build commit
id: set-artifact-commit
env:
GH_TOKEN: ${{ github.token }}
run: |
# If run-id was used, get the commit from the download-latest-artifacts-run-id step
if [ "${{ inputs.build-web-run-id }}" ]; then
echo "commit=${{ steps.download-latest-artifacts-run-id.outputs.artifact-build-commit }}" >> $GITHUB_OUTPUT
elif [ "${{ steps.download-latest-artifacts.outcome }}" == "failure" ]; then
# If the download-latest-artifacts step failed, query the GH API to get the commit SHA of the artifact that was just built with trigger-build-web.
commit=$(gh api /repos/bitwarden/clients/actions/runs/${{ steps.trigger-build-web.outputs.workflow_id }}/artifacts --jq '.artifacts[0].workflow_run.head_sha')
echo "commit=$commit" >> $GITHUB_OUTPUT
else
# Set the commit to the output of step download-latest-artifacts.
echo "commit=${{ steps.download-latest-artifacts.outputs.artifact-build-commit }}" >> $GITHUB_OUTPUT
fi
notify-start:
name: Notify Slack with start message
needs:
- approval
- setup
- artifact-check
runs-on: ubuntu-22.04
if: ${{ always() && ( contains( inputs.environment , 'QA' ) || contains( inputs.environment , 'DEV' ) ) }}
outputs:
channel_id: ${{ steps.slack-message.outputs.channel_id }}
ts: ${{ steps.slack-message.outputs.ts }}
steps:
- name: Notify Slack with start message
uses: bitwarden/gh-actions/report-deployment-status-to-slack@main
id: slack-message
with:
project: Clients
environment: ${{ needs.setup.outputs.environment-name }}
tag: ${{ inputs.branch-or-tag }}
slack-channel: ${{ needs.setup.outputs.slack-channel-name }}
event: 'start'
commit-sha: ${{ needs.artifact-check.outputs.artifact-build-commit }}
url: https://github.com/bitwarden/clients/actions/runs/${{ github.run_id }}
AZURE_KV_CI_SERVICE_PRINCIPAL: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
update-summary:
name: Display commit
needs: artifact-check
runs-on: ubuntu-22.04
steps:
- name: Display commit SHA
run: |
REPO_URL="https://github.com/bitwarden/clients/commit"
COMMIT_SHA="${{ needs.artifact-check.outputs.artifact-build-commit }}"
echo ":steam_locomotive: View [commit]($REPO_URL/$COMMIT_SHA)" >> $GITHUB_STEP_SUMMARY
azure-deploy:
name: Deploy Web Vault to ${{ inputs.environment }} Storage Account
needs:
- setup
- artifact-check
- approval
runs-on: ubuntu-22.04
env:
_ENVIRONMENT: ${{ needs.setup.outputs.environment }}
_ENVIRONMENT_URL: ${{ needs.setup.outputs.environment-url }}
_ENVIRONMENT_NAME: ${{ needs.setup.outputs.environment-name }}
_ENVIRONMENT_ARTIFACT: ${{ needs.setup.outputs.environment-artifact }}
steps:
- name: Create GitHub deployment
uses: chrnorm/deployment-action@55729fcebec3d284f60f5bcabbd8376437d696b1 # v2.0.7
id: deployment
with:
token: '${{ secrets.GITHUB_TOKEN }}'
initial-status: 'in_progress'
environment-url: ${{ env._ENVIRONMENT_URL }}
environment: ${{ env._ENVIRONMENT_NAME }}
task: 'deploy'
description: 'Deployment from branch/tag: ${{ inputs.branch-or-tag }}'
ref: ${{ needs.artifact-check.outputs.artifact-build-commit }}
- name: Login to Azure
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets[needs.setup.outputs.azure-login-creds] }}
- name: Retrieve Storage Account connection string for az sync
if: ${{ needs.setup.outputs.sync-utility == 'az-sync' }}
id: retrieve-secrets-az-sync
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: ${{ needs.setup.outputs.retrieve-secrets-keyvault }}
secrets: "sa-bitwarden-web-vault-dev-key-temp"
- name: Retrieve Storage Account name and SPN credentials for azcopy
if: ${{ needs.setup.outputs.sync-utility == 'azcopy' }}
id: retrieve-secrets-azcopy
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: ${{ needs.setup.outputs.retrieve-secrets-keyvault }}
secrets: "sa-bitwarden-web-vault-name,sp-bitwarden-web-vault-password,sp-bitwarden-web-vault-appid,sp-bitwarden-web-vault-tenant"
- name: 'Download latest cloud asset using GitHub Run ID: ${{ inputs.build-web-run-id }}'
if: ${{ inputs.build-web-run-id }}
uses: bitwarden/gh-actions/download-artifacts@main
id: download-latest-artifacts
continue-on-error: true
with:
workflow: build-web.yml
path: apps/web
workflow_conclusion: success
run_id: ${{ inputs.build-web-run-id }}
artifacts: ${{ env._ENVIRONMENT_ARTIFACT }}
- name: 'Download cloud asset from branch/tag: ${{ inputs.branch-or-tag }}'
if: ${{ !inputs.build-web-run-id }}
uses: bitwarden/gh-actions/download-artifacts@main
with:
workflow: build-web.yml
path: apps/web
workflow_conclusion: success
branch: ${{ inputs.branch-or-tag }}
artifacts: ${{ env._ENVIRONMENT_ARTIFACT }}
- name: Unzip build asset
working-directory: apps/web
run: unzip ${{ env._ENVIRONMENT_ARTIFACT }}
- name: Sync to Azure Storage Account using az storage blob sync
if: ${{ needs.setup.outputs.sync-utility == 'az-sync' }}
working-directory: apps/web
run: |
az storage blob sync \
--source "./build" \
--container '$web' \
--connection-string "${{ steps.retrieve-secrets-az-sync.outputs.sa-bitwarden-web-vault-dev-key-temp }}" \
--delete-destination=${{ inputs.force-delete-destination }}
- name: Sync to Azure Storage Account using azcopy
if: ${{ needs.setup.outputs.sync-utility == 'azcopy' }}
working-directory: apps/web
env:
AZCOPY_AUTO_LOGIN_TYPE: SPN
AZCOPY_SPA_APPLICATION_ID: ${{ steps.retrieve-secrets-azcopy.outputs.sp-bitwarden-web-vault-appid }}
AZCOPY_SPA_CLIENT_SECRET: ${{ steps.retrieve-secrets-azcopy.outputs.sp-bitwarden-web-vault-password }}
AZCOPY_TENANT_ID: ${{ steps.retrieve-secrets-azcopy.outputs.sp-bitwarden-web-vault-tenant }}
run: |
azcopy sync ./build 'https://${{ steps.retrieve-secrets-azcopy.outputs.sa-bitwarden-web-vault-name }}.blob.core.windows.net/$web/' \
--delete-destination=${{ inputs.force-delete-destination }} --compare-hash="MD5"
- name: Debug sync logs
if: ${{ inputs.debug }}
run: cat /home/runner/.azcopy/*.log
- name: Debug index.html
if: ${{ inputs.debug }}
run: cat apps/web/build/index.html
- name: Update deployment status to Success
if: success()
uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3
with:
token: '${{ secrets.GITHUB_TOKEN }}'
environment-url: ${{ env._ENVIRONMENT_URL }}
state: 'success'
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
- name: Update deployment status to Failure
if: failure()
uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3
with:
token: '${{ secrets.GITHUB_TOKEN }}'
environment-url: ${{ env._ENVIRONMENT_URL }}
state: 'failure'
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
notify:
name: Notify Slack with result
runs-on: ubuntu-22.04
if: ${{ always() && ( contains( inputs.environment , 'QA' ) || contains( inputs.environment , 'DEV' ) ) }}
needs:
- setup
- notify-start
- azure-deploy
- artifact-check
steps:
- name: Notify Slack with result
uses: bitwarden/gh-actions/report-deployment-status-to-slack@main
with:
project: Clients
environment: ${{ needs.setup.outputs.environment-name }}
tag: ${{ inputs.branch-or-tag }}
slack-channel: ${{ needs.notify-start.outputs.channel_id }}
event: ${{ needs.azure-deploy.result }}
url: https://github.com/bitwarden/clients/actions/runs/${{ github.run_id }}
commit-sha: ${{ needs.artifact-check.outputs.artifact-build-commit }}
update-ts: ${{ needs.notify-start.outputs.ts }}
AZURE_KV_CI_SERVICE_PRINCIPAL: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}

View File

@@ -1,4 +1,3 @@
---
name: Enforce PR labels
on:
@@ -8,7 +7,7 @@ on:
jobs:
enforce-label:
name: EnforceLabel
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- name: Enforce Label
uses: yogevbd/enforce-label-action@a3c219da6b8fa73f6ba62b68ff09c469b3a1c024 # 2.2.2

View File

@@ -1,23 +0,0 @@
# Runs creation of Pull Requests
# If the PR destination branch is master, add a needs-qa label
---
name: Label Issue Pull Request
on:
pull_request:
types:
- opened # Check when PR is opened
paths-ignore:
- .github/workflows/** # We don't need QA on workflow changes
branches:
- 'master' # We only want to check when PRs target master
jobs:
add-needs-qa-label:
runs-on: ubuntu-latest
steps:
- name: Add label to pull request
uses: andymckay/labeler@e6c4322d0397f3240f0e7e30a33b5c5df2d39e90 # 1.0.4
if: ${{ !github.event.pull_request.head.repo.fork }}
with:
add-labels: "needs-qa"

View File

@@ -1,4 +1,3 @@
---
name: Lint
on:
@@ -18,10 +17,10 @@ defaults:
jobs:
lint:
name: Lint
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Lint filenames (no capital characters)
run: |
@@ -35,15 +34,25 @@ jobs:
! -path "*/.DS_Store" \
! -path "*/*locales/*" \
! -path "./.github/*" \
! -path "*/Cargo.toml" \
! -path "*/Cargo.lock" \
! -path "./apps/desktop/macos/*" \
> tmp.txt
diff <(sort .github/whitelist-capital-letters.txt) <(sort tmp.txt)
- name: Get Node Version
id: retrieve-node-version
run: |
NODE_NVMRC=$(cat .nvmrc)
NODE_VERSION=${NODE_NVMRC/v/''}
echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT
- name: Set up Node
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
node-version: '18'
node-version: ${{ steps.retrieve-node-version.outputs.node_version }}
- name: Run linter
run: |

33
.github/workflows/locales-lint.yml vendored Normal file
View File

@@ -0,0 +1,33 @@
name: Locales lint for Crowdin
on:
pull_request:
branches-ignore:
- 'l10n_master'
- 'cf-pages'
paths:
- '**/messages.json'
jobs:
lint:
name: Lint
runs-on: ubuntu-22.04
steps:
- name: Checkout repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Checkout base branch repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.base.sha }}
path: base
- name: Install dependencies
run: npm ci
- name: Compare
run: |
npm run test:locales
if [ $? -eq 0 ]; then
echo "Lint check successful."
else
echo "Lint check failed."
exit 1
fi

233
.github/workflows/publish-cli.yml vendored Normal file
View File

@@ -0,0 +1,233 @@
name: Publish CLI
run-name: Publish CLI ${{ inputs.publish_type }}
on:
workflow_dispatch:
inputs:
publish_type:
description: 'Publish Options'
required: true
default: 'Initial Publish'
type: choice
options:
- Initial Publish
- Republish
- Dry Run
version:
description: 'Version to publish (default: latest cli release)'
required: true
type: string
default: latest
snap_publish:
description: 'Publish to Snap store'
required: true
default: true
type: boolean
choco_publish:
description: 'Publish to Chocolatey store'
required: true
default: true
type: boolean
npm_publish:
description: 'Publish to npm registry'
required: true
default: true
type: boolean
defaults:
run:
working-directory: apps/cli
jobs:
setup:
name: Setup
runs-on: ubuntu-22.04
outputs:
release-version: ${{ steps.version-output.outputs.version }}
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
defaults:
run:
working-directory: .
steps:
- name: Branch check
if: ${{ inputs.publish_type != 'Dry Run' }}
run: |
if [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ "$GITHUB_REF" != "refs/heads/hotfix-rc-cli" ]]; then
echo "==================================="
echo "[!] Can only publish from the 'rc' or 'hotfix-rc-cli' branches"
echo "==================================="
exit 1
fi
- name: Version output
id: version-output
run: |
if [[ "${{ inputs.version }}" == "latest" || "${{ inputs.version }}" == "" ]]; then
VERSION=$(curl "https://api.github.com/repos/bitwarden/clients/releases" | jq -c '.[] | select(.tag_name | contains("cli")) | .tag_name' | head -1 | grep -ohE '20[0-9]{2}\.([1-9]|1[0-2])\.[0-9]+')
echo "Latest Released Version: $VERSION"
echo "version=$VERSION" >> $GITHUB_OUTPUT
else
echo "Release Version: ${{ inputs.version }}"
echo "version=${{ inputs.version }}" >> $GITHUB_OUTPUT
fi
- name: Create GitHub deployment
if: ${{ inputs.publish_type != 'Dry Run' }}
uses: chrnorm/deployment-action@55729fcebec3d284f60f5bcabbd8376437d696b1 # v2.0.7
id: deployment
with:
token: '${{ secrets.GITHUB_TOKEN }}'
initial-status: 'in_progress'
environment: 'CLI - Production'
description: 'Deployment ${{ steps.version-output.outputs.version }} from branch ${{ github.ref_name }}'
task: release
snap:
name: Deploy Snap
runs-on: ubuntu-22.04
needs: setup
if: inputs.snap_publish
env:
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
steps:
- name: Checkout repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Login to Azure
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "snapcraft-store-token"
- name: Install Snap
uses: samuelmeuli/action-snapcraft@d33c176a9b784876d966f80fb1b461808edc0641 # v2.1.1
- name: Download artifacts
run: wget https://github.com/bitwarden/clients/releases/download/cli-v${{ env._PKG_VERSION }}/bw_${{ env._PKG_VERSION }}_amd64.snap
- name: Publish Snap & logout
if: ${{ inputs.publish_type != 'Dry Run' }}
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ steps.retrieve-secrets.outputs.snapcraft-store-token }}
run: |
snapcraft upload bw_${{ env._PKG_VERSION }}_amd64.snap --release stable
snapcraft logout
choco:
name: Deploy Choco
runs-on: windows-2022
needs: setup
if: inputs.choco_publish
env:
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
steps:
- name: Checkout repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Login to Azure
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "cli-choco-api-key"
- name: Setup Chocolatey
run: choco apikey --key $env:CHOCO_API_KEY --source https://push.chocolatey.org/
env:
CHOCO_API_KEY: ${{ steps.retrieve-secrets.outputs.cli-choco-api-key }}
- name: Make dist dir
run: New-Item -ItemType directory -Path ./dist
- name: Download artifacts
run: Invoke-WebRequest -Uri "https://github.com/bitwarden/clients/releases/download/cli-v${{ env._PKG_VERSION }}/bitwarden-cli.${{ env._PKG_VERSION }}.nupkg" -OutFile bitwarden-cli.${{ env._PKG_VERSION }}.nupkg
working-directory: apps/cli/dist
- name: Push to Chocolatey
if: ${{ inputs.publish_type != 'Dry Run' }}
run: choco push --source=https://push.chocolatey.org/
working-directory: apps/cli/dist
npm:
name: Publish NPM
runs-on: ubuntu-22.04
needs: setup
if: inputs.npm_publish
env:
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
steps:
- name: Checkout repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Login to Azure
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "npm-api-key"
- name: Download and set up artifact
run: |
mkdir -p build
wget https://github.com/bitwarden/clients/releases/download/cli-v${{ env._PKG_VERSION }}/bitwarden-cli-${{ env._PKG_VERSION }}-npm-build.zip
unzip bitwarden-cli-${{ env._PKG_VERSION }}-npm-build.zip -d build
- name: Setup NPM
run: |
echo 'registry="https://registry.npmjs.org/"' > ./.npmrc
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ./.npmrc
env:
NPM_TOKEN: ${{ steps.retrieve-secrets.outputs.npm-api-key }}
- name: Install Husky
run: npm install -g husky
- name: Publish NPM
if: ${{ inputs.publish_type != 'Dry Run' }}
run: npm publish --access public --regsitry=https://registry.npmjs.org/ --userconfig=./.npmrc
update-deployment:
name: Update Deployment Status
runs-on: ubuntu-22.04
needs:
- setup
- npm
- snap
- choco
if: ${{ always() && inputs.publish_type != 'Dry Run' }}
steps:
- name: Check if any job failed
if: contains(needs.*.result, 'failure')
run: exit 1
- name: Update deployment status to Success
if: ${{ inputs.publish_type != 'Dry Run' && success() }}
uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3
with:
token: '${{ secrets.GITHUB_TOKEN }}'
state: 'success'
deployment-id: ${{ needs.setup.outputs.deployment-id }}
- name: Update deployment status to Failure
if: ${{ inputs.publish_type != 'Dry Run' && failure() }}
uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3
with:
token: '${{ secrets.GITHUB_TOKEN }}'
state: 'failure'
deployment-id: ${{ needs.setup.outputs.deployment-id }}

295
.github/workflows/publish-desktop.yml vendored Normal file
View File

@@ -0,0 +1,295 @@
name: Publish Desktop
run-name: Publish Desktop ${{ inputs.publish_type }}
on:
workflow_dispatch:
inputs:
publish_type:
description: 'Publish Options'
required: true
default: 'Initial Publish'
type: choice
options:
- Initial Publish
- Republish
- Dry Run
version:
description: 'Version to publish (default: latest desktop release)'
required: true
type: string
default: latest
rollout_percentage:
description: 'Staged Rollout Percentage'
required: true
default: '10'
type: string
snap_publish:
description: 'Publish to Snap store'
required: true
default: true
type: boolean
choco_publish:
description: 'Publish to Chocolatey store'
required: true
default: true
type: boolean
jobs:
setup:
name: Setup
runs-on: ubuntu-22.04
outputs:
release-version: ${{ steps.version.outputs.version }}
release-channel: ${{ steps.release-channel.outputs.channel }}
tag-name: ${{ steps.version.outputs.tag_name }}
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
steps:
- name: Branch check
if: ${{ inputs.publish_type != 'Dry Run' }}
run: |
if [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ "$GITHUB_REF" != "refs/heads/hotfix-rc-desktop" ]]; then
echo "==================================="
echo "[!] Can only publish from the 'rc' or 'hotfix-rc-desktop' branches"
echo "==================================="
exit 1
fi
- name: Check Publish Version
id: version
run: |
if [[ "${{ inputs.version }}" == "latest" || "${{ inputs.version }}" == "" ]]; then
TAG_NAME=$(curl "https://api.github.com/repos/bitwarden/clients/releases" | jq -c '.[] | select(.tag_name | contains("desktop")) | .tag_name' | head -1 | cut -d '"' -f 2)
VERSION=$(echo $TAG_NAME | sed "s/desktop-v//")
echo "Latest Released Version: $VERSION"
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Tag name: $TAG_NAME"
echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT
else
echo "Release Version: ${{ inputs.version }}"
echo "version=${{ inputs.version }}"
$TAG_NAME="desktop-v${{ inputs.version }}"
echo "Tag name: $TAG_NAME"
echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT
fi
- name: Get Version Channel
id: release-channel
run: |
case "${{ steps.version.outputs.version }}" in
*"alpha"*)
echo "channel=alpha" >> $GITHUB_OUTPUT
echo "[!] We do not yet support 'alpha'"
exit 1
;;
*"beta"*)
echo "channel=beta" >> $GITHUB_OUTPUT
;;
*)
echo "channel=latest" >> $GITHUB_OUTPUT
;;
esac
- name: Create GitHub deployment
if: ${{ inputs.publish_type != 'Dry Run' }}
uses: chrnorm/deployment-action@55729fcebec3d284f60f5bcabbd8376437d696b1 # v2.0.7
id: deployment
with:
token: '${{ secrets.GITHUB_TOKEN }}'
initial-status: 'in_progress'
environment: 'Desktop - Production'
description: 'Deployment ${{ steps.version.outputs.version }} to channel ${{ steps.release-channel.outputs.channel }} from branch ${{ github.ref_name }}'
task: release
electron-blob:
name: Electron blob publish
runs-on: ubuntu-22.04
needs: setup
env:
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
_RELEASE_TAG: ${{ needs.setup.outputs.tag-name }}
steps:
- name: Login to Azure
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "aws-electron-access-id,
aws-electron-access-key,
aws-electron-bucket-name"
- name: Create artifacts directory
run: mkdir -p apps/desktop/artifacts
- name: Download artifacts
env:
GH_TOKEN: ${{ github.token }}
working-directory: apps/desktop/artifacts
run: gh release download ${{ env._RELEASE_TAG }} -R bitwarden/clients
- name: Set staged rollout percentage
env:
RELEASE_CHANNEL: ${{ needs.setup.outputs.release-channel }}
ROLLOUT_PCT: ${{ inputs.rollout_percentage }}
run: |
echo "stagingPercentage: ${ROLLOUT_PCT}" >> apps/desktop/artifacts/${RELEASE_CHANNEL}.yml
echo "stagingPercentage: ${ROLLOUT_PCT}" >> apps/desktop/artifacts/${RELEASE_CHANNEL}-linux.yml
echo "stagingPercentage: ${ROLLOUT_PCT}" >> apps/desktop/artifacts/${RELEASE_CHANNEL}-mac.yml
- name: Publish artifacts to S3
if: ${{ inputs.publish_type != 'Dry Run' }}
env:
AWS_ACCESS_KEY_ID: ${{ steps.retrieve-secrets.outputs.aws-electron-access-id }}
AWS_SECRET_ACCESS_KEY: ${{ steps.retrieve-secrets.outputs.aws-electron-access-key }}
AWS_DEFAULT_REGION: 'us-west-2'
AWS_S3_BUCKET_NAME: ${{ steps.retrieve-secrets.outputs.aws-electron-bucket-name }}
working-directory: apps/desktop/artifacts
run: |
aws s3 cp ./ $AWS_S3_BUCKET_NAME/desktop/ \
--acl "public-read" \
--recursive \
--quiet
- name: Update deployment status to Success
if: ${{ inputs.publish_type != 'Dry Run' && success() }}
uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3
with:
token: '${{ secrets.GITHUB_TOKEN }}'
state: 'success'
deployment-id: ${{ needs.setup.outputs.deployment-id }}
- name: Update deployment status to Failure
if: ${{ inputs.publish_type != 'Dry Run' && failure() }}
uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3
with:
token: '${{ secrets.GITHUB_TOKEN }}'
state: 'failure'
deployment-id: ${{ needs.setup.outputs.deployment-id }}
snap:
name: Deploy Snap
runs-on: ubuntu-22.04
needs: setup
if: inputs.snap_publish
env:
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
_RELEASE_TAG: ${{ needs.setup.outputs.tag-name }}
steps:
- name: Checkout Repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Login to Azure
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "snapcraft-store-token"
- name: Install Snap
uses: samuelmeuli/action-snapcraft@d33c176a9b784876d966f80fb1b461808edc0641 # v2.1.1
- name: Setup
run: mkdir dist
working-directory: apps/desktop
- name: Download artifacts
working-directory: apps/desktop/dist
run: wget https://github.com/bitwarden/clients/releases/download/${{ env._RELEASE_TAG }}/bitwarden_${{ env._PKG_VERSION }}_amd64.snap
- name: Deploy to Snap Store
if: ${{ inputs.publish_type != 'Dry Run' }}
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ steps.retrieve-secrets.outputs.snapcraft-store-token }}
run: |
snapcraft upload bitwarden_${{ env._PKG_VERSION }}_amd64.snap --release stable
snapcraft logout
working-directory: apps/desktop/dist
choco:
name: Deploy Choco
runs-on: windows-2022
needs: setup
if: inputs.choco_publish
env:
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
_RELEASE_TAG: ${{ needs.setup.outputs.tag-name }}
steps:
- name: Checkout Repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Print Environment
run: |
dotnet --version
dotnet nuget --version
- name: Login to Azure
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "cli-choco-api-key"
- name: Setup Chocolatey
run: choco apikey --key $env:CHOCO_API_KEY --source https://push.chocolatey.org/
env:
CHOCO_API_KEY: ${{ steps.retrieve-secrets.outputs.cli-choco-api-key }}
- name: Make dist dir
run: New-Item -ItemType directory -Path ./dist
working-directory: apps/desktop
- name: Download artifacts
working-directory: apps/desktop/dist
run: Invoke-WebRequest -Uri "https://github.com/bitwarden/clients/releases/download/${{ env._RELEASE_TAG }}/bitwarden.${{ env._PKG_VERSION }}.nupkg" -OutFile bitwarden.${{ env._PKG_VERSION }}.nupkg
- name: Push to Chocolatey
if: ${{ inputs.publish_type != 'Dry Run' }}
run: choco push --source=https://push.chocolatey.org/
working-directory: apps/desktop/dist
update-deployment:
name: Update Deployment Status
runs-on: ubuntu-22.04
needs:
- setup
- electron-blob
- snap
- choco
if: ${{ always() && inputs.publish_type != 'Dry Run' }}
steps:
- name: Check if any job failed
if: contains(needs.*.result, 'failure')
run: exit 1
- name: Update deployment status to Success
if: ${{ inputs.publish_type != 'Dry Run' && success() }}
uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3
with:
token: '${{ secrets.GITHUB_TOKEN }}'
state: 'success'
deployment-id: ${{ needs.setup.outputs.deployment-id }}
- name: Update deployment status to Failure
if: ${{ inputs.publish_type != 'Dry Run' && failure() }}
uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3
with:
token: '${{ secrets.GITHUB_TOKEN }}'
state: 'failure'
deployment-id: ${{ needs.setup.outputs.deployment-id }}

143
.github/workflows/publish-web.yml vendored Normal file
View File

@@ -0,0 +1,143 @@
name: Publish Web
run-name: Publish Web ${{ inputs.publish_type }}
on:
workflow_dispatch:
inputs:
publish_type:
description: 'Publish Options'
required: true
default: 'Initial Release'
type: choice
options:
- Initial Release
- Redeploy
- Dry Run
env:
_AZ_REGISTRY: bitwardenprod.azurecr.io
jobs:
setup:
name: Setup
runs-on: ubuntu-22.04
outputs:
release_version: ${{ steps.version.outputs.version }}
tag_version: ${{ steps.version.outputs.tag }}
steps:
- name: Checkout repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Branch check
if: ${{ inputs.publish_type != 'Dry Run' }}
run: |
if [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ "$GITHUB_REF" != "refs/heads/hotfix-rc-web" ]]; then
echo "==================================="
echo "[!] Can only publish from the 'rc' or 'hotfix-rc-web' branches"
echo "==================================="
exit 1
fi
- name: Check Release Version
id: version
uses: bitwarden/gh-actions/release-version-check@main
with:
release-type: ${{ inputs.publish_type }}
project-type: ts
file: apps/web/package.json
monorepo: true
monorepo-project: web
self-host:
name: Release self-host docker
runs-on: ubuntu-22.04
needs: setup
env:
_BRANCH_NAME: ${{ github.ref_name }}
_RELEASE_VERSION: ${{ needs.setup.outputs.release_version }}
_RELEASE_OPTION: ${{ inputs.publish_type }}
steps:
- name: Print environment
run: |
whoami
docker --version
echo "GitHub ref: $GITHUB_REF"
echo "GitHub event: $GITHUB_EVENT"
echo "Github Release Option: $_RELEASE_OPTION"
- name: Checkout repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
########## ACR ##########
- name: Login to Azure - PROD Subscription
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
- name: Login to Azure ACR
run: az acr login -n bitwardenprod
- name: Create GitHub deployment
if: ${{ inputs.publish_type != 'Dry Run' }}
uses: chrnorm/deployment-action@55729fcebec3d284f60f5bcabbd8376437d696b1 # v2.0.7
id: deployment
with:
token: '${{ secrets.GITHUB_TOKEN }}'
initial-status: 'in_progress'
environment-url: http://vault.bitwarden.com
environment: 'Web Vault - US Production Cloud'
description: 'Deployment ${{ needs.setup.outputs.release_version }} from branch ${{ github.ref_name }}'
task: release
- name: Pull branch image
run: |
if [[ "${{ inputs.publish_type }}" == "Dry Run" ]]; then
docker pull $_AZ_REGISTRY/web:latest
else
docker pull $_AZ_REGISTRY/web:$_BRANCH_NAME
fi
- name: Tag version
run: |
if [[ "${{ inputs.publish_type }}" == "Dry Run" ]]; then
docker tag $_AZ_REGISTRY/web:latest $_AZ_REGISTRY/web:dryrun
docker tag $_AZ_REGISTRY/web:latest $_AZ_REGISTRY/web-sh:dryrun
else
docker tag $_AZ_REGISTRY/web:$_BRANCH_NAME $_AZ_REGISTRY/web:$_RELEASE_VERSION
docker tag $_AZ_REGISTRY/web:$_BRANCH_NAME $_AZ_REGISTRY/web-sh:$_RELEASE_VERSION
docker tag $_AZ_REGISTRY/web:$_BRANCH_NAME $_AZ_REGISTRY/web:latest
docker tag $_AZ_REGISTRY/web:$_BRANCH_NAME $_AZ_REGISTRY/web-sh:latest
fi
- name: Push version
run: |
if [[ "${{ inputs.publish_type }}" == "Dry Run" ]]; then
docker push $_AZ_REGISTRY/web:dryrun
docker push $_AZ_REGISTRY/web-sh:dryrun
else
docker push $_AZ_REGISTRY/web:$_RELEASE_VERSION
docker push $_AZ_REGISTRY/web-sh:$_RELEASE_VERSION
docker push $_AZ_REGISTRY/web:latest
docker push $_AZ_REGISTRY/web-sh:latest
fi
- name: Update deployment status to Success
if: ${{ inputs.publish_type != 'Dry Run' && success() }}
uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3
with:
token: '${{ secrets.GITHUB_TOKEN }}'
environment-url: http://vault.bitwarden.com
state: 'success'
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
- name: Update deployment status to Failure
if: ${{ inputs.publish_type != 'Dry Run' && failure() }}
uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3
with:
token: '${{ secrets.GITHUB_TOKEN }}'
environment-url: http://vault.bitwarden.com
state: 'failure'
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
- name: Log out of Docker
run: docker logout

View File

@@ -1,4 +1,3 @@
---
name: Release Browser
run-name: Release Browser ${{ inputs.release_type }}
@@ -27,7 +26,7 @@ jobs:
release-version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Branch check
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
@@ -41,7 +40,7 @@ jobs:
- name: Check Release Version
id: version
uses: bitwarden/gh-actions/release-version-check@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
uses: bitwarden/gh-actions/release-version-check@main
with:
release-type: ${{ github.event.inputs.release_type }}
project-type: ts
@@ -56,7 +55,7 @@ jobs:
needs: setup
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Testing locales - extName length
run: |
@@ -91,19 +90,9 @@ jobs:
- setup
- locales-test
steps:
- name: Create GitHub deployment
uses: chrnorm/deployment-action@d42cde7132fcec920de534fffc3be83794335c00 # v2.0.5
id: deployment
with:
token: '${{ secrets.GITHUB_TOKEN }}'
initial-status: 'in_progress'
environment: 'Browser - Production'
description: 'Deployment ${{ needs.setup.outputs.release-version }} from branch ${{ github.ref_name }}'
task: release
- name: Download latest Release build artifacts
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
uses: bitwarden/gh-actions/download-artifacts@main
with:
workflow: build-browser.yml
workflow_conclusion: success
@@ -114,13 +103,13 @@ jobs:
dist-firefox-*.zip,
dist-edge-*.zip'
- name: Dry Run - Download latest master build artifacts
- name: Dry Run - Download latest build artifacts
if: ${{ github.event.inputs.release_type == 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
uses: bitwarden/gh-actions/download-artifacts@main
with:
workflow: build-browser.yml
workflow_conclusion: success
branch: master
branch: main
artifacts: 'browser-source-*.zip,
dist-chrome-*.zip,
dist-opera-*.zip,
@@ -139,7 +128,7 @@ jobs:
- name: Create release
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: ncipollo/release-action@a2e71bdd4e7dab70ca26a852f29600c98b33153e # v1.12.0
uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.0
with:
artifacts: 'browser-source-${{ needs.setup.outputs.release-version }}.zip,
dist-chrome-${{ needs.setup.outputs.release-version }}.zip,
@@ -152,19 +141,3 @@ jobs:
body: "<insert release notes here>"
token: ${{ secrets.GITHUB_TOKEN }}
draft: true
- name: Update deployment status to Success
if: ${{ success() }}
uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1
with:
token: '${{ secrets.GITHUB_TOKEN }}'
state: 'success'
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
- name: Update deployment status to Failure
if: ${{ failure() }}
uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1
with:
token: '${{ secrets.GITHUB_TOKEN }}'
state: 'failure'
deployment-id: ${{ steps.deployment.outputs.deployment_id }}

View File

@@ -1,4 +1,3 @@
---
name: Release CLI
run-name: Release CLI ${{ inputs.release_type }}
@@ -14,22 +13,6 @@ on:
- Initial Release
- Redeploy
- Dry Run
snap_publish:
description: 'Publish to snap store'
required: true
default: true
type: boolean
choco_publish:
description: 'Publish to chocolatey store'
required: true
default: true
type: boolean
npm_publish:
description: 'Publish to npm registry'
required: true
default: true
type: boolean
defaults:
run:
@@ -38,15 +21,15 @@ defaults:
jobs:
setup:
name: Setup
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
outputs:
release-version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Branch check
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
if: ${{ inputs.release_type != 'Dry Run' }}
run: |
if [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ "$GITHUB_REF" != "refs/heads/hotfix-rc-cli" ]]; then
echo "==================================="
@@ -57,28 +40,22 @@ jobs:
- name: Check Release Version
id: version
uses: bitwarden/gh-actions/release-version-check@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
uses: bitwarden/gh-actions/release-version-check@main
with:
release-type: ${{ github.event.inputs.release_type }}
release-type: ${{ inputs.release_type }}
project-type: ts
file: apps/cli/package.json
monorepo: true
monorepo-project: cli
- name: Create GitHub deployment
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: chrnorm/deployment-action@d42cde7132fcec920de534fffc3be83794335c00 # v2.0.5
id: deployment
with:
token: '${{ secrets.GITHUB_TOKEN }}'
initial-status: 'in_progress'
environment: 'CLI - Production'
description: 'Deployment ${{ steps.version.outputs.version }} from branch ${{ github.ref_name }}'
task: release
release:
name: Release
runs-on: ubuntu-22.04
needs: setup
steps:
- name: Download all Release artifacts
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
if: ${{ inputs.release_type != 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@main
with:
workflow: build-cli.yml
path: apps/cli
@@ -86,220 +63,39 @@ jobs:
branch: ${{ github.ref_name }}
- name: Dry Run - Download all artifacts
if: ${{ github.event.inputs.release_type == 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
if: ${{ inputs.release_type == 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@main
with:
workflow: build-cli.yml
path: apps/cli
workflow_conclusion: success
branch: master
branch: main
- name: Create release
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: ncipollo/release-action@a2e71bdd4e7dab70ca26a852f29600c98b33153e # v1.12.0
if: ${{ inputs.release_type != 'Dry Run' }}
uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.0
env:
PKG_VERSION: ${{ steps.version.outputs.version }}
PKG_VERSION: ${{ needs.setup.outputs.release-version }}
with:
artifacts: "apps/cli/bw-windows-${{ env.PKG_VERSION }}.zip,
artifacts: "apps/cli/bw-oss-windows-${{ env.PKG_VERSION }}.zip,
apps/cli/bw-oss-windows-sha256-${{ env.PKG_VERSION }}.txt,
apps/cli/bw-windows-${{ env.PKG_VERSION }}.zip,
apps/cli/bw-windows-sha256-${{ env.PKG_VERSION }}.txt,
apps/cli/bw-oss-macos-${{ env.PKG_VERSION }}.zip,
apps/cli/bw-oss-macos-sha256-${{ env.PKG_VERSION }}.txt,
apps/cli/bw-macos-${{ env.PKG_VERSION }}.zip,
apps/cli/bw-macos-sha256-${{ env.PKG_VERSION }}.txt,
apps/cli/bw-oss-linux-${{ env.PKG_VERSION }}.zip,
apps/cli/bw-oss-linux-sha256-${{ env.PKG_VERSION }}.txt,
apps/cli/bw-linux-${{ env.PKG_VERSION }}.zip,
apps/cli/bw-linux-sha256-${{ env.PKG_VERSION }}.txt,
apps/cli/bitwarden-cli.${{ env.PKG_VERSION }}.nupkg,
apps/cli/bw_${{ env.PKG_VERSION }}_amd64.snap,
apps/cli/bw-snap-sha256-${{ env.PKG_VERSION }}.txt"
apps/cli/bw-snap-sha256-${{ env.PKG_VERSION }}.txt,
apps/cli/bitwarden-cli-${{ env.PKG_VERSION }}-npm-build.zip"
commit: ${{ github.sha }}
tag: cli-v${{ env.PKG_VERSION }}
name: CLI v${{ env.PKG_VERSION }}
body: "<insert release notes here>"
token: ${{ secrets.GITHUB_TOKEN }}
draft: true
- name: Update deployment status to Success
if: ${{ github.event.inputs.release_type != 'Dry Run' && success() }}
uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1
with:
token: '${{ secrets.GITHUB_TOKEN }}'
state: 'success'
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
- name: Update deployment status to Failure
if: ${{ github.event.inputs.release_type != 'Dry Run' && failure() }}
uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1
with:
token: '${{ secrets.GITHUB_TOKEN }}'
state: 'failure'
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
snap:
name: Deploy Snap
runs-on: ubuntu-20.04
needs: setup
if: inputs.snap_publish
env:
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Login to Azure
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
keyvault: "bitwarden-ci"
secrets: "snapcraft-store-token"
- name: Install Snap
uses: samuelmeuli/action-snapcraft@d33c176a9b784876d966f80fb1b461808edc0641 # v2.1.1
with:
snapcraft_token: ${{ steps.retrieve-secrets.outputs.snapcraft-store-token }}
- name: Download artifacts
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
workflow: build-cli.yml
path: apps/cli
workflow_conclusion: success
branch: ${{ github.ref_name }}
artifacts: bw_${{ env._PKG_VERSION }}_amd64.snap
- name: Dry Run - Download artifacts
if: ${{ github.event.inputs.release_type == 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
workflow: build-cli.yml
path: apps/cli
workflow_conclusion: success
branch: master
artifacts: bw_${{ env._PKG_VERSION }}_amd64.snap
- name: Publish Snap & logout
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ steps.retrieve-secrets.outputs.snapcraft-store-token }}
run: |
snapcraft push bw_${{ env._PKG_VERSION }}_amd64.snap --release stable
snapcraft logout
choco:
name: Deploy Choco
runs-on: windows-2019
needs: setup
if: inputs.choco_publish
env:
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Login to Azure
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
keyvault: "bitwarden-ci"
secrets: "cli-choco-api-key"
- name: Setup Chocolatey
run: choco apikey --key $env:CHOCO_API_KEY --source https://push.chocolatey.org/
env:
CHOCO_API_KEY: ${{ steps.retrieve-secrets.outputs.cli-choco-api-key }}
- name: Make dist dir
shell: pwsh
run: New-Item -ItemType directory -Path ./dist
- name: Download artifacts
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
workflow: build-cli.yml
path: apps/cli/dist
workflow_conclusion: success
branch: ${{ github.ref_name }}
artifacts: bitwarden-cli.${{ env._PKG_VERSION }}.nupkg
- name: Dry Run - Download artifacts
if: ${{ github.event.inputs.release_type == 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
workflow: build-cli.yml
path: apps/cli/dist
workflow_conclusion: success
branch: master
artifacts: bitwarden-cli.${{ env._PKG_VERSION }}.nupkg
- name: Push to Chocolatey
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
shell: pwsh
run: |
cd dist
choco push --source=https://push.chocolatey.org/
npm:
name: Publish NPM
runs-on: ubuntu-20.04
needs: setup
if: inputs.npm_publish
env:
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Login to Azure
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
keyvault: "bitwarden-ci"
secrets: "npm-api-key"
- name: Download artifacts
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
workflow: build-cli.yml
path: apps/cli/build
workflow_conclusion: success
branch: ${{ github.ref_name }}
artifacts: bitwarden-cli-${{ env._PKG_VERSION }}-npm-build.zip
- name: Dry Run - Download artifacts
if: ${{ github.event.inputs.release_type == 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
workflow: build-cli.yml
path: apps/cli/build
workflow_conclusion: success
branch: master
artifacts: bitwarden-cli-${{ env._PKG_VERSION }}-npm-build.zip
- name: Setup NPM
run: |
echo 'registry="https://registry.npmjs.org/"' > ./.npmrc
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ./.npmrc
env:
NPM_TOKEN: ${{ steps.retrieve-secrets.outputs.npm-api-key }}
- name: Install Husky
run: npm install -g husky
- name: Publish NPM
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
run: npm publish --access public --regsitry=https://registry.npmjs.org/ --userconfig=./.npmrc

View File

@@ -1,4 +1,3 @@
---
name: Release Desktop Beta
on:
@@ -15,21 +14,22 @@ defaults:
jobs:
setup:
name: Setup
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
outputs:
release-version: ${{ steps.version.outputs.version }}
release-channel: ${{ steps.release-channel.outputs.channel }}
branch-name: ${{ steps.branch.outputs.branch-name }}
build_number: ${{ steps.increment-version.outputs.build_number }}
node_version: ${{ steps.retrieve-node-version.outputs.node_version }}
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Branch check
run: |
if [[ "$GITHUB_REF" != "refs/heads/master" ]] && [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ "$GITHUB_REF" != "refs/heads/hotfix-rc" ]]; then
if [[ "$GITHUB_REF" != "refs/heads/main" ]] && [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ "$GITHUB_REF" != "refs/heads/hotfix-rc" ]]; then
echo "==================================="
echo "[!] Can only release from the 'master', 'rc' or 'hotfix-rc' branches"
echo "[!] Can only release from the 'main', 'rc' or 'hotfix-rc' branches"
echo "==================================="
exit 1
fi
@@ -47,7 +47,7 @@ jobs:
- name: Check Release Version
id: version
uses: bitwarden/gh-actions/release-version-check@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
uses: bitwarden/gh-actions/release-version-check@main
with:
release-type: 'Initial Release'
project-type: ts
@@ -104,35 +104,36 @@ jobs:
echo "branch-name=$branch_name" >> $GITHUB_OUTPUT
- name: Get Node Version
id: retrieve-node-version
run: |
NODE_NVMRC=$(cat .nvmrc)
NODE_VERSION=${NODE_NVMRC/v/''}
echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT
linux:
name: Linux Build
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
needs: setup
env:
_PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }}
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
NODE_OPTIONS: --max_old_space_size=4096
defaults:
run:
working-directory: apps/desktop
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ needs.setup.outputs.branch-name }}
- name: Set up Node
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
node-version: '18'
- name: Set Node options
run: echo "NODE_OPTIONS=--max_old_space_size=4096" >> $GITHUB_ENV
- name: Install node-gyp
run: |
npm install -g node-gyp
node-gyp install $(node -v)
node-version: ${{ env._NODE_VERSION }}
- name: Set up environment
run: |
@@ -157,42 +158,42 @@ jobs:
run: npm run dist:lin
- name: Upload .deb artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: Bitwarden-${{ env._PACKAGE_VERSION }}-amd64.deb
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-amd64.deb
if-no-files-found: error
- name: Upload .rpm artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.rpm
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.rpm
if-no-files-found: error
- name: Upload .freebsd artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64.freebsd
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64.freebsd
if-no-files-found: error
- name: Upload .snap artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: bitwarden_${{ env._PACKAGE_VERSION }}_amd64.snap
path: apps/desktop/dist/bitwarden_${{ env._PACKAGE_VERSION }}_amd64.snap
if-no-files-found: error
- name: Upload .AppImage artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.AppImage
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.AppImage
if-no-files-found: error
- name: Upload auto-update artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: ${{ needs.setup.outputs.release-channel }}-linux.yml
path: apps/desktop/dist/${{ needs.setup.outputs.release-channel }}-linux.yml
@@ -201,7 +202,7 @@ jobs:
windows:
name: Windows Build
runs-on: windows-2019
runs-on: windows-2022
needs: setup
defaults:
run:
@@ -209,29 +210,23 @@ jobs:
working-directory: apps/desktop
env:
_PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }}
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
NODE_OPTIONS: --max_old_space_size=4096
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ needs.setup.outputs.branch-name }}
- name: Set up Node
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
node-version: '18'
- name: Set Node options
run: echo "NODE_OPTIONS=--max_old_space_size=4096" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- name: Install node-gyp
run: |
npm install -g node-gyp
node-gyp install $(node -v)
node-version: ${{ env._NODE_VERSION }}
- name: Install AST
uses: bitwarden/gh-actions/install-ast@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
run: dotnet tool install --global AzureSignTool --version 4.0.1
- name: Set up environment
run: choco install checksum --no-progress
@@ -243,13 +238,13 @@ jobs:
choco --version
- name: Login to Azure
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "code-signing-vault-url,
@@ -304,91 +299,91 @@ jobs:
-NewName bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z
- name: Upload portable exe artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: Bitwarden-Portable-${{ env._PACKAGE_VERSION }}.exe
path: apps/desktop/dist/Bitwarden-Portable-${{ env._PACKAGE_VERSION }}.exe
if-no-files-found: error
- name: Upload installer exe artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: Bitwarden-Installer-${{ env._PACKAGE_VERSION }}.exe
path: apps/desktop/dist/nsis-web/Bitwarden-Installer-${{ env._PACKAGE_VERSION }}.exe
if-no-files-found: error
- name: Upload appx ia32 artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: Bitwarden-${{ env._PACKAGE_VERSION }}-ia32.appx
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-ia32.appx
if-no-files-found: error
- name: Upload store appx ia32 artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: Bitwarden-${{ env._PACKAGE_VERSION }}-ia32-store.appx
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-ia32-store.appx
if-no-files-found: error
- name: Upload NSIS ia32 artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: bitwarden-${{ env._PACKAGE_VERSION }}-ia32.nsis.7z
path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-ia32.nsis.7z
if-no-files-found: error
- name: Upload appx x64 artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64.appx
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64.appx
if-no-files-found: error
- name: Upload store appx x64 artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64-store.appx
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64-store.appx
if-no-files-found: error
- name: Upload NSIS x64 artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: bitwarden-${{ env._PACKAGE_VERSION }}-x64.nsis.7z
path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-x64.nsis.7z
if-no-files-found: error
- name: Upload appx ARM64 artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: Bitwarden-${{ env._PACKAGE_VERSION }}-arm64.appx
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-arm64.appx
if-no-files-found: error
- name: Upload store appx ARM64 artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: Bitwarden-${{ env._PACKAGE_VERSION }}-arm64-store.appx
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-arm64-store.appx
if-no-files-found: error
- name: Upload NSIS ARM64 artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z
path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z
if-no-files-found: error
- name: Upload nupkg artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: bitwarden.${{ env._PACKAGE_VERSION }}.nupkg
path: apps/desktop/dist/chocolatey/bitwarden.${{ env._PACKAGE_VERSION }}.nupkg
if-no-files-found: error
- name: Upload auto-update artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: ${{ needs.setup.outputs.release-channel }}.yml
path: apps/desktop/dist/nsis-web/${{ needs.setup.outputs.release-channel }}.yml
@@ -397,33 +392,30 @@ jobs:
macos-build:
name: MacOS Build
runs-on: macos-11
runs-on: macos-13
needs: setup
env:
_PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }}
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
NODE_OPTIONS: --max_old_space_size=4096
defaults:
run:
working-directory: apps/desktop
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ needs.setup.outputs.branch-name }}
- name: Set up Node
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
node-version: '18'
node-version: ${{ env._NODE_VERSION }}
- name: Set Node options
run: echo "NODE_OPTIONS=--max_old_space_size=4096" >> $GITHUB_ENV
- name: Install node-gyp
run: |
npm install -g node-gyp
node-gyp install $(node -v)
- name: Set up Node-gyp
run: python3 -m pip install setuptools
- name: Print environment
run: |
@@ -434,70 +426,78 @@ jobs:
- name: Cache Build
id: build-cache
uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1
uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2
with:
path: apps/desktop/build
key: ${{ runner.os }}-${{ github.run_id }}-build
- name: Cache Safari
id: safari-cache
uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1
uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2
with:
path: apps/browser/dist/Safari
key: ${{ runner.os }}-${{ github.run_id }}-safari-extension
- name: Decrypt secrets
- name: Download Provisioning Profiles secrets
env:
DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }}
ACCOUNT_NAME: bitwardenci
CONTAINER_NAME: profiles
run: |
mkdir -p $HOME/secrets
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/bitwarden-desktop-key.p12" \
"$GITHUB_WORKSPACE/.github/secrets/bitwarden-desktop-key.p12.gpg"
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/appstore-app-cert.p12" \
"$GITHUB_WORKSPACE/.github/secrets/appstore-app-cert.p12.gpg"
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/appstore-installer-cert.p12" \
"$GITHUB_WORKSPACE/.github/secrets/appstore-installer-cert.p12.gpg"
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/devid-app-cert.p12" \
"$GITHUB_WORKSPACE/.github/secrets/devid-app-cert.p12.gpg"
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/devid-installer-cert.p12" \
"$GITHUB_WORKSPACE/.github/secrets/devid-installer-cert.p12.gpg"
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/macdev-cert.p12" \
"$GITHUB_WORKSPACE/.github/secrets/macdev-cert.p12.gpg"
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/bitwarden_desktop_appstore.provisionprofile" \
"$GITHUB_WORKSPACE/.github/secrets/bitwarden_desktop_appstore.provisionprofile.gpg"
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
--name bitwarden_desktop_appstore.provisionprofile \
--file $HOME/secrets/bitwarden_desktop_appstore.provisionprofile \
--output none
- name: Get certificates
run: |
mkdir -p $HOME/certificates
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/bitwarden-desktop-key |
jq -r .value | base64 -d > $HOME/certificates/bitwarden-desktop-key.p12
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-app-cert |
jq -r .value | base64 -d > $HOME/certificates/appstore-app-cert.p12
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-installer-cert |
jq -r .value | base64 -d > $HOME/certificates/appstore-installer-cert.p12
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-app-cert |
jq -r .value | base64 -d > $HOME/certificates/devid-app-cert.p12
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-installer-cert |
jq -r .value | base64 -d > $HOME/certificates/devid-installer-cert.p12
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/macdev-cert |
jq -r .value | base64 -d > $HOME/certificates/macdev-cert.p12
- name: Set up keychain
env:
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
DESKTOP_KEY_PASSWORD: ${{ secrets.DESKTOP_KEY_PASSWORD }}
DEVID_CERT_PASSWORD: ${{ secrets.DEVID_CERT_PASSWORD }}
APPSTORE_CERT_PASSWORD: ${{ secrets.APPSTORE_CERT_PASSWORD }}
MACDEV_CERT_PASSWORD: ${{ secrets.MACDEV_CERT_PASSWORD }}
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
run: |
security create-keychain -p $KEYCHAIN_PASSWORD build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p $KEYCHAIN_PASSWORD build.keychain
security set-keychain-settings -lut 1200 build.keychain
security import "$HOME/secrets/bitwarden-desktop-key.p12" -k build.keychain -P $DESKTOP_KEY_PASSWORD \
security import "$HOME/certificates/bitwarden-desktop-key.p12" -k build.keychain -P "" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import "$HOME/secrets/devid-app-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \
security import "$HOME/certificates/devid-app-cert.p12" -k build.keychain -P "" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import "$HOME/secrets/devid-installer-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \
security import "$HOME/certificates/devid-installer-cert.p12" -k build.keychain -P "" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import "$HOME/secrets/appstore-app-cert.p12" -k build.keychain -P $APPSTORE_CERT_PASSWORD \
security import "$HOME/certificates/appstore-app-cert.p12" -k build.keychain -P "" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import "$HOME/secrets/appstore-installer-cert.p12" -k build.keychain -P $APPSTORE_CERT_PASSWORD \
security import "$HOME/certificates/appstore-installer-cert.p12" -k build.keychain -P "" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import "$HOME/secrets/macdev-cert.p12" -k build.keychain -P $MACDEV_CERT_PASSWORD \
security import "$HOME/certificates/macdev-cert.p12" -k build.keychain -P "" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $KEYCHAIN_PASSWORD build.keychain
- name: Set up provisioning profiles
@@ -524,35 +524,32 @@ jobs:
macos-package-github:
name: MacOS Package GitHub Release Assets
runs-on: macos-11
runs-on: macos-13
needs:
- setup
- macos-build
env:
_PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }}
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
NODE_OPTIONS: --max_old_space_size=4096
defaults:
run:
working-directory: apps/desktop
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ needs.setup.outputs.branch-name }}
- name: Set up Node
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
node-version: '18'
node-version: ${{ env._NODE_VERSION }}
- name: Set Node options
run: echo "NODE_OPTIONS=--max_old_space_size=4096" >> $GITHUB_ENV
- name: Install node-gyp
run: |
npm install -g node-gyp
node-gyp install $(node -v)
- name: Set up Node-gyp
run: python3 -m pip install setuptools
- name: Print environment
run: |
@@ -563,70 +560,84 @@ jobs:
- name: Get Build Cache
id: build-cache
uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1
uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2
with:
path: apps/desktop/build
key: ${{ runner.os }}-${{ github.run_id }}-build
- name: Setup Safari Cache
id: safari-cache
uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1
uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2
with:
path: apps/browser/dist/Safari
key: ${{ runner.os }}-${{ github.run_id }}-safari-extension
- name: Decrypt secrets
- name: Login to Azure
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Download Provisioning Profiles secrets
env:
DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }}
ACCOUNT_NAME: bitwardenci
CONTAINER_NAME: profiles
run: |
mkdir -p $HOME/secrets
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/bitwarden-desktop-key.p12" \
"$GITHUB_WORKSPACE/.github/secrets/bitwarden-desktop-key.p12.gpg"
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/appstore-app-cert.p12" \
"$GITHUB_WORKSPACE/.github/secrets/appstore-app-cert.p12.gpg"
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/appstore-installer-cert.p12" \
"$GITHUB_WORKSPACE/.github/secrets/appstore-installer-cert.p12.gpg"
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/devid-app-cert.p12" \
"$GITHUB_WORKSPACE/.github/secrets/devid-app-cert.p12.gpg"
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/devid-installer-cert.p12" \
"$GITHUB_WORKSPACE/.github/secrets/devid-installer-cert.p12.gpg"
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/macdev-cert.p12" \
"$GITHUB_WORKSPACE/.github/secrets/macdev-cert.p12.gpg"
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/bitwarden_desktop_appstore.provisionprofile" \
"$GITHUB_WORKSPACE/.github/secrets/bitwarden_desktop_appstore.provisionprofile.gpg"
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
--name bitwarden_desktop_appstore.provisionprofile \
--file $HOME/secrets/bitwarden_desktop_appstore.provisionprofile \
--output none
- name: Get certificates
run: |
mkdir -p $HOME/certificates
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/bitwarden-desktop-key |
jq -r .value | base64 -d > $HOME/certificates/bitwarden-desktop-key.p12
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-app-cert |
jq -r .value | base64 -d > $HOME/certificates/appstore-app-cert.p12
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-installer-cert |
jq -r .value | base64 -d > $HOME/certificates/appstore-installer-cert.p12
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-app-cert |
jq -r .value | base64 -d > $HOME/certificates/devid-app-cert.p12
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-installer-cert |
jq -r .value | base64 -d > $HOME/certificates/devid-installer-cert.p12
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/macdev-cert |
jq -r .value | base64 -d > $HOME/certificates/macdev-cert.p12
- name: Set up keychain
env:
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
DESKTOP_KEY_PASSWORD: ${{ secrets.DESKTOP_KEY_PASSWORD }}
DEVID_CERT_PASSWORD: ${{ secrets.DEVID_CERT_PASSWORD }}
APPSTORE_CERT_PASSWORD: ${{ secrets.APPSTORE_CERT_PASSWORD }}
MACDEV_CERT_PASSWORD: ${{ secrets.MACDEV_CERT_PASSWORD }}
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
run: |
security create-keychain -p $KEYCHAIN_PASSWORD build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p $KEYCHAIN_PASSWORD build.keychain
security set-keychain-settings -lut 1200 build.keychain
security import "$HOME/secrets/bitwarden-desktop-key.p12" -k build.keychain -P $DESKTOP_KEY_PASSWORD \
security import "$HOME/certificates/bitwarden-desktop-key.p12" -k build.keychain -P "" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import "$HOME/secrets/devid-app-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \
security import "$HOME/certificates/devid-app-cert.p12" -k build.keychain -P "" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import "$HOME/secrets/devid-installer-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \
security import "$HOME/certificates/devid-installer-cert.p12" -k build.keychain -P "" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import "$HOME/secrets/appstore-app-cert.p12" -k build.keychain -P $APPSTORE_CERT_PASSWORD \
security import "$HOME/certificates/appstore-app-cert.p12" -k build.keychain -P "" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import "$HOME/secrets/appstore-installer-cert.p12" -k build.keychain -P $APPSTORE_CERT_PASSWORD \
security import "$HOME/certificates/appstore-installer-cert.p12" -k build.keychain -P "" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import "$HOME/secrets/macdev-cert.p12" -k build.keychain -P $MACDEV_CERT_PASSWORD \
security import "$HOME/certificates/macdev-cert.p12" -k build.keychain -P "" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $KEYCHAIN_PASSWORD build.keychain
- name: Set up provisioning profiles
@@ -653,7 +664,7 @@ jobs:
- name: Download artifact from hotfix-rc
if: github.ref == 'refs/heads/hotfix-rc'
uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0
uses: bitwarden/gh-actions/download-artifacts@main
with:
workflow: build-browser.yml
workflow_conclusion: success
@@ -662,20 +673,20 @@ jobs:
- name: Download artifact from rc
if: github.ref == 'refs/heads/rc'
uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0
uses: bitwarden/gh-actions/download-artifacts@main
with:
workflow: build-browser.yml
workflow_conclusion: success
branch: rc
path: ${{ github.workspace }}/browser-build-artifacts
- name: Download artifact from master
- name: Download artifacts from main
if: ${{ github.ref != 'refs/heads/rc' && github.ref != 'refs/heads/hotfix-rc' }}
uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0
uses: bitwarden/gh-actions/download-artifacts@main
with:
workflow: build-browser.yml
workflow_conclusion: success
branch: master
branch: main
path: ${{ github.workspace }}/browser-build-artifacts
- name: Unzip Safari artifact
@@ -696,28 +707,28 @@ jobs:
run: npm run pack:mac
- name: Upload .zip artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal-mac.zip
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal-mac.zip
if-no-files-found: error
- name: Upload .dmg artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg
if-no-files-found: error
- name: Upload .dmg blockmap artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg.blockmap
path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg.blockmap
if-no-files-found: error
- name: Upload auto-update artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: ${{ needs.setup.outputs.release-channel }}-mac.yml
path: apps/desktop/dist/${{ needs.setup.outputs.release-channel }}-mac.yml
@@ -726,35 +737,32 @@ jobs:
macos-package-mas:
name: MacOS Package Prod Release Asset
runs-on: macos-11
runs-on: macos-13
needs:
- setup
- macos-build
env:
_PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }}
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
NODE_OPTIONS: --max_old_space_size=4096
defaults:
run:
working-directory: apps/desktop
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ needs.setup.outputs.branch-name }}
- name: Set up Node
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
node-version: '18'
node-version: ${{ env._NODE_VERSION }}
- name: Set Node options
run: echo "NODE_OPTIONS=--max_old_space_size=4096" >> $GITHUB_ENV
- name: Install node-gyp
run: |
npm install -g node-gyp
node-gyp install $(node -v)
- name: Set up Node-gyp
run: python3 -m pip install setuptools
- name: Print environment
run: |
@@ -765,70 +773,79 @@ jobs:
- name: Get Build Cache
id: build-cache
uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1
uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2
with:
path: apps/desktop/build
key: ${{ runner.os }}-${{ github.run_id }}-build
- name: Setup Safari Cache
id: safari-cache
uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1
uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2
with:
path: apps/browser/dist/Safari
key: ${{ runner.os }}-${{ github.run_id }}-safari-extension
- name: Decrypt secrets
- name: Download Provisioning Profiles secrets
env:
DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }}
ACCOUNT_NAME: bitwardenci
CONTAINER_NAME: profiles
run: |
mkdir -p $HOME/secrets
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/bitwarden-desktop-key.p12" \
"$GITHUB_WORKSPACE/.github/secrets/bitwarden-desktop-key.p12.gpg"
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/appstore-app-cert.p12" \
"$GITHUB_WORKSPACE/.github/secrets/appstore-app-cert.p12.gpg"
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/appstore-installer-cert.p12" \
"$GITHUB_WORKSPACE/.github/secrets/appstore-installer-cert.p12.gpg"
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/devid-app-cert.p12" \
"$GITHUB_WORKSPACE/.github/secrets/devid-app-cert.p12.gpg"
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/devid-installer-cert.p12" \
"$GITHUB_WORKSPACE/.github/secrets/devid-installer-cert.p12.gpg"
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/macdev-cert.p12" \
"$GITHUB_WORKSPACE/.github/secrets/macdev-cert.p12.gpg"
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output "$HOME/secrets/bitwarden_desktop_appstore.provisionprofile" \
"$GITHUB_WORKSPACE/.github/secrets/bitwarden_desktop_appstore.provisionprofile.gpg"
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
--name bitwarden_desktop_appstore.provisionprofile \
--file $HOME/secrets/bitwarden_desktop_appstore.provisionprofile \
--output none
- name: Get certificates
run: |
mkdir -p $HOME/certificates
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/bitwarden-desktop-key |
jq -r .value | base64 -d > $HOME/certificates/bitwarden-desktop-key.p12
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-app-cert |
jq -r .value | base64 -d > $HOME/certificates/appstore-app-cert.p12
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-installer-cert |
jq -r .value | base64 -d > $HOME/certificates/appstore-installer-cert.p12
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-app-cert |
jq -r .value | base64 -d > $HOME/certificates/devid-app-cert.p12
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-installer-cert |
jq -r .value | base64 -d > $HOME/certificates/devid-installer-cert.p12
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/macdev-cert |
jq -r .value | base64 -d > $HOME/certificates/macdev-cert.p12
- name: Set up keychain
env:
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
DESKTOP_KEY_PASSWORD: ${{ secrets.DESKTOP_KEY_PASSWORD }}
DEVID_CERT_PASSWORD: ${{ secrets.DEVID_CERT_PASSWORD }}
APPSTORE_CERT_PASSWORD: ${{ secrets.APPSTORE_CERT_PASSWORD }}
MACDEV_CERT_PASSWORD: ${{ secrets.MACDEV_CERT_PASSWORD }}
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
run: |
security create-keychain -p $KEYCHAIN_PASSWORD build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p $KEYCHAIN_PASSWORD build.keychain
security set-keychain-settings -lut 1200 build.keychain
security import "$HOME/secrets/bitwarden-desktop-key.p12" -k build.keychain -P $DESKTOP_KEY_PASSWORD \
security import "$HOME/certificates/bitwarden-desktop-key.p12" -k build.keychain -P "" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import "$HOME/secrets/devid-app-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \
security import "$HOME/certificates/devid-app-cert.p12" -k build.keychain -P "" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import "$HOME/secrets/devid-installer-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \
security import "$HOME/certificates/devid-installer-cert.p12" -k build.keychain -P "" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import "$HOME/secrets/appstore-app-cert.p12" -k build.keychain -P $APPSTORE_CERT_PASSWORD \
security import "$HOME/certificates/appstore-app-cert.p12" -k build.keychain -P "" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import "$HOME/secrets/appstore-installer-cert.p12" -k build.keychain -P $APPSTORE_CERT_PASSWORD \
security import "$HOME/certificates/appstore-installer-cert.p12" -k build.keychain -P "" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import "$HOME/secrets/macdev-cert.p12" -k build.keychain -P $MACDEV_CERT_PASSWORD \
security import "$HOME/certificates/macdev-cert.p12" -k build.keychain -P "" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $KEYCHAIN_PASSWORD build.keychain
- name: Set up provisioning profiles
@@ -855,7 +872,7 @@ jobs:
- name: Download artifact from hotfix-rc
if: github.ref == 'refs/heads/hotfix-rc'
uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0
uses: bitwarden/gh-actions/download-artifacts@main
with:
workflow: build-browser.yml
workflow_conclusion: success
@@ -864,20 +881,20 @@ jobs:
- name: Download artifact from rc
if: github.ref == 'refs/heads/rc'
uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0
uses: bitwarden/gh-actions/download-artifacts@main
with:
workflow: build-browser.yml
workflow_conclusion: success
branch: rc
path: ${{ github.workspace }}/browser-build-artifacts
- name: Download artifact from master
- name: Download artifact from main
if: ${{ github.ref != 'refs/heads/rc' && github.ref != 'refs/heads/hotfix-rc' }}
uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0
uses: bitwarden/gh-actions/download-artifacts@main
with:
workflow: build-browser.yml
workflow_conclusion: success
branch: master
branch: main
path: ${{ github.workspace }}/browser-build-artifacts
- name: Unzip Safari artifact
@@ -898,7 +915,7 @@ jobs:
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
- name: Upload .pkg artifact
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.pkg
path: apps/desktop/dist/mas-universal/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.pkg
@@ -906,7 +923,7 @@ jobs:
release:
name: Release beta channel to S3
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
needs:
- setup
- linux
@@ -916,7 +933,7 @@ jobs:
- macos-package-mas
steps:
- name: Create GitHub deployment
uses: chrnorm/deployment-action@d42cde7132fcec920de534fffc3be83794335c00 # v2.0.5
uses: chrnorm/deployment-action@55729fcebec3d284f60f5bcabbd8376437d696b1 # v2.0.7
id: deployment
with:
token: '${{ secrets.GITHUB_TOKEN }}'
@@ -926,25 +943,21 @@ jobs:
task: release
- name: Login to Azure
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "aws-electron-access-id,
aws-electron-access-key,
aws-electron-bucket-name,
r2-electron-access-id,
r2-electron-access-key,
r2-electron-bucket-name,
cf-prod-account"
aws-electron-bucket-name"
- name: Download all artifacts
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
path: apps/desktop/artifacts
@@ -967,23 +980,9 @@ jobs:
--recursive \
--quiet
- name: Publish artifacts to R2
env:
AWS_ACCESS_KEY_ID: ${{ steps.retrieve-secrets.outputs.r2-electron-access-id }}
AWS_SECRET_ACCESS_KEY: ${{ steps.retrieve-secrets.outputs.r2-electron-access-key }}
AWS_DEFAULT_REGION: 'us-east-1'
AWS_S3_BUCKET_NAME: ${{ steps.retrieve-secrets.outputs.r2-electron-bucket-name }}
CF_ACCOUNT: ${{ steps.retrieve-secrets.outputs.cf-prod-account }}
working-directory: apps/desktop/artifacts
run: |
aws s3 cp ./ $AWS_S3_BUCKET_NAME/desktop/ \
--recursive \
--quiet \
--endpoint-url https://${CF_ACCOUNT}.r2.cloudflarestorage.com
- name: Update deployment status to Success
if: ${{ success() }}
uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1
uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3
with:
token: '${{ secrets.GITHUB_TOKEN }}'
state: 'success'
@@ -991,7 +990,7 @@ jobs:
- name: Update deployment status to Failure
if: ${{ failure() }}
uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1
uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3
with:
token: '${{ secrets.GITHUB_TOKEN }}'
state: 'failure'
@@ -999,7 +998,7 @@ jobs:
remove-branch:
name: Remove branch
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
if: always()
needs:
- setup
@@ -1011,7 +1010,7 @@ jobs:
- release
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup git config
run: |

View File

@@ -1,4 +1,3 @@
---
name: Release Desktop
run-name: Release Desktop ${{ inputs.release_type }}
@@ -6,39 +5,13 @@ on:
workflow_dispatch:
inputs:
release_type:
description: 'Release Options'
description: 'Release Type'
required: true
default: 'Initial Release'
default: 'Release'
type: choice
options:
- Initial Release
- Redeploy
- Release
- Dry Run
rollout_percentage:
description: 'Staged Rollout Percentage'
required: true
default: '10'
type: string
snap_publish:
description: 'Publish to Snap store'
required: true
default: true
type: boolean
choco_publish:
description: 'Publish to Chocolatey store'
required: true
default: true
type: boolean
electron_publish:
description: 'Publish electron to S3 bucket'
required: true
default: true
type: boolean
github_release:
description: 'Publish github release'
required: true
default: true
type: boolean
defaults:
run:
@@ -53,7 +26,7 @@ jobs:
release-channel: ${{ steps.release-channel.outputs.channel }}
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Branch check
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
@@ -67,7 +40,7 @@ jobs:
- name: Check Release Version
id: version
uses: bitwarden/gh-actions/release-version-check@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
uses: bitwarden/gh-actions/release-version-check@main
with:
release-type: ${{ inputs.release_type }}
project-type: ts
@@ -92,38 +65,9 @@ jobs:
;;
esac
- name: Create GitHub deployment
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: chrnorm/deployment-action@d42cde7132fcec920de534fffc3be83794335c00 # v2.0.5
id: deployment
with:
token: '${{ secrets.GITHUB_TOKEN }}'
initial-status: 'in_progress'
environment: 'Desktop - Production'
description: 'Deployment ${{ steps.version.outputs.version }} to channel ${{ steps.release-channel.outputs.channel }} from branch ${{ github.ref_name }}'
task: release
- name: Login to Azure
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
keyvault: "bitwarden-ci"
secrets: "aws-electron-access-id,
aws-electron-access-key,
aws-electron-bucket-name,
r2-electron-access-id,
r2-electron-access-key,
r2-electron-bucket-name,
cf-prod-account"
- name: Download all artifacts
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
uses: bitwarden/gh-actions/download-artifacts@main
with:
workflow: build-desktop.yml
workflow_conclusion: success
@@ -132,11 +76,11 @@ jobs:
- name: Dry Run - Download all artifacts
if: ${{ github.event.inputs.release_type == 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
uses: bitwarden/gh-actions/download-artifacts@main
with:
workflow: build-desktop.yml
workflow_conclusion: success
branch: master
branch: main
path: apps/desktop/artifacts
- name: Rename .pkg to .pkg.archive
@@ -145,54 +89,15 @@ jobs:
working-directory: apps/desktop/artifacts
run: mv Bitwarden-${{ env.PKG_VERSION }}-universal.pkg Bitwarden-${{ env.PKG_VERSION }}-universal.pkg.archive
- name: Set staged rollout percentage
if: ${{ github.event.inputs.electron_publish == 'true' }}
env:
RELEASE_CHANNEL: ${{ steps.release-channel.outputs.channel }}
ROLLOUT_PCT: ${{ inputs.rollout_percentage }}
run: |
echo "stagingPercentage: ${ROLLOUT_PCT}" >> apps/desktop/artifacts/${RELEASE_CHANNEL}.yml
echo "stagingPercentage: ${ROLLOUT_PCT}" >> apps/desktop/artifacts/${RELEASE_CHANNEL}-linux.yml
echo "stagingPercentage: ${ROLLOUT_PCT}" >> apps/desktop/artifacts/${RELEASE_CHANNEL}-mac.yml
- name: Publish artifacts to S3
if: ${{ github.event.inputs.release_type != 'Dry Run' && github.event.inputs.electron_publish == 'true' }}
env:
AWS_ACCESS_KEY_ID: ${{ steps.retrieve-secrets.outputs.aws-electron-access-id }}
AWS_SECRET_ACCESS_KEY: ${{ steps.retrieve-secrets.outputs.aws-electron-access-key }}
AWS_DEFAULT_REGION: 'us-west-2'
AWS_S3_BUCKET_NAME: ${{ steps.retrieve-secrets.outputs.aws-electron-bucket-name }}
working-directory: apps/desktop/artifacts
run: |
aws s3 cp ./ $AWS_S3_BUCKET_NAME/desktop/ \
--acl "public-read" \
--recursive \
--quiet
- name: Publish artifacts to R2
if: ${{ github.event.inputs.release_type != 'Dry Run' && github.event.inputs.electron_publish == 'true' }}
env:
AWS_ACCESS_KEY_ID: ${{ steps.retrieve-secrets.outputs.r2-electron-access-id }}
AWS_SECRET_ACCESS_KEY: ${{ steps.retrieve-secrets.outputs.r2-electron-access-key }}
AWS_DEFAULT_REGION: 'us-east-1'
AWS_S3_BUCKET_NAME: ${{ steps.retrieve-secrets.outputs.r2-electron-bucket-name }}
CF_ACCOUNT: ${{ steps.retrieve-secrets.outputs.cf-prod-account }}
working-directory: apps/desktop/artifacts
run: |
aws s3 cp ./ $AWS_S3_BUCKET_NAME/desktop/ \
--recursive \
--quiet \
--endpoint-url https://${CF_ACCOUNT}.r2.cloudflarestorage.com
- name: Get checksum files
uses: bitwarden/gh-actions/get-checksum@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
uses: bitwarden/gh-actions/get-checksum@main
with:
packages_dir: "apps/desktop/artifacts"
file_path: "apps/desktop/artifacts/sha256-checksums.txt"
- name: Create Release
uses: ncipollo/release-action@a2e71bdd4e7dab70ca26a852f29600c98b33153e # v1.12.0
if: ${{ steps.release-channel.outputs.channel == 'latest' && github.event.inputs.release_type != 'Dry Run' && github.event.inputs.github_release == 'true' }}
uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.0
if: ${{ steps.release-channel.outputs.channel == 'latest' && github.event.inputs.release_type != 'Dry Run' }}
env:
PKG_VERSION: ${{ steps.version.outputs.version }}
RELEASE_CHANNEL: ${{ steps.release-channel.outputs.channel }}
@@ -228,145 +133,3 @@ jobs:
body: "<insert release notes here>"
token: ${{ secrets.GITHUB_TOKEN }}
draft: true
- name: Update deployment status to Success
if: ${{ github.event.inputs.release_type != 'Dry Run' && success() }}
uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1
with:
token: '${{ secrets.GITHUB_TOKEN }}'
state: 'success'
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
- name: Update deployment status to Failure
if: ${{ github.event.inputs.release_type != 'Dry Run' && failure() }}
uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1
with:
token: '${{ secrets.GITHUB_TOKEN }}'
state: 'failure'
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
snap:
name: Deploy Snap
runs-on: ubuntu-22.04
needs: setup
if: ${{ github.event.inputs.snap_publish == 'true' }}
env:
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
steps:
- name: Checkout Repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Login to Azure
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
keyvault: "bitwarden-ci"
secrets: "snapcraft-store-token"
- name: Install Snap
uses: samuelmeuli/action-snapcraft@d33c176a9b784876d966f80fb1b461808edc0641 # v2.1.1
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ steps.retrieve-secrets.outputs.snapcraft-store-token }}
- name: Setup
run: mkdir dist
working-directory: apps/desktop
- name: Download Snap artifact
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
workflow: build-desktop.yml
workflow_conclusion: success
branch: ${{ github.ref_name }}
artifacts: bitwarden_${{ env._PKG_VERSION }}_amd64.snap
path: apps/desktop/dist
- name: Dry Run - Download Snap artifact
if: ${{ github.event.inputs.release_type == 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
workflow: build-desktop.yml
workflow_conclusion: success
branch: master
artifacts: bitwarden_${{ env._PKG_VERSION }}_amd64.snap
path: apps/desktop/dist
- name: Deploy to Snap Store
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ steps.retrieve-secrets.outputs.snapcraft-store-token }}
run: |
/snap/bin/snapcraft upload bitwarden_${{ env._PKG_VERSION }}_amd64.snap --release stable
/snap/bin/snapcraft logout
working-directory: apps/desktop/dist
choco:
name: Deploy Choco
runs-on: windows-2019
needs: setup
if: ${{ github.event.inputs.choco_publish == 'true' }}
env:
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
steps:
- name: Checkout Repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Print Environment
run: |
dotnet --version
dotnet nuget --version
- name: Login to Azure
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
keyvault: "bitwarden-ci"
secrets: "cli-choco-api-key"
- name: Setup Chocolatey
shell: pwsh
run: choco apikey --key $env:CHOCO_API_KEY --source https://push.chocolatey.org/
env:
CHOCO_API_KEY: ${{ steps.retrieve-secrets.outputs.cli-choco-api-key }}
- name: Make dist dir
shell: pwsh
run: New-Item -ItemType directory -Path ./dist
working-directory: apps/desktop
- name: Download choco artifact
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
workflow: build-desktop.yml
workflow_conclusion: success
branch: ${{ github.ref_name }}
artifacts: bitwarden.${{ env._PKG_VERSION }}.nupkg
path: apps/desktop/dist
- name: Dry Run - Download choco artifact
if: ${{ github.event.inputs.release_type == 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
workflow: build-desktop.yml
workflow_conclusion: success
branch: master
artifacts: bitwarden.${{ env._PKG_VERSION }}.nupkg
path: apps/desktop/dist
- name: Push to Chocolatey
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
shell: pwsh
run: choco push --source=https://push.chocolatey.org/
working-directory: apps/desktop/dist

View File

@@ -1,4 +1,3 @@
---
name: Release Web
run-name: Release Web ${{ inputs.release_type }}
@@ -15,9 +14,6 @@ on:
- Redeploy
- Dry Run
env:
_AZ_REGISTRY: bitwardenprod.azurecr.io
jobs:
setup:
name: Setup
@@ -27,7 +23,7 @@ jobs:
tag_version: ${{ steps.version.outputs.tag }}
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Branch check
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
@@ -41,7 +37,7 @@ jobs:
- name: Check Release Version
id: version
uses: bitwarden/gh-actions/release-version-check@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
uses: bitwarden/gh-actions/release-version-check@main
with:
release-type: ${{ github.event.inputs.release_type }}
project-type: ts
@@ -49,185 +45,15 @@ jobs:
monorepo: true
monorepo-project: web
self-host:
name: Release self-host docker
runs-on: ubuntu-22.04
needs: setup
env:
_BRANCH_NAME: ${{ github.ref_name }}
_RELEASE_VERSION: ${{ needs.setup.outputs.release_version }}
_RELEASE_OPTION: ${{ github.event.inputs.release_type }}
steps:
- name: Print environment
run: |
whoami
docker --version
echo "GitHub ref: $GITHUB_REF"
echo "GitHub event: $GITHUB_EVENT"
echo "Github Release Option: $_RELEASE_OPTION"
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
########## ACR ##########
- name: Login to Azure - PROD Subscription
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
with:
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
- name: Login to Azure ACR
run: az acr login -n bitwardenprod
- name: Pull branch image
run: |
if [[ "${{ github.event.inputs.release_type }}" == "Dry Run" ]]; then
docker pull $_AZ_REGISTRY/web:latest
else
docker pull $_AZ_REGISTRY/web:$_BRANCH_NAME
fi
- name: Tag version
run: |
if [[ "${{ github.event.inputs.release_type }}" == "Dry Run" ]]; then
docker tag $_AZ_REGISTRY/web:latest $_AZ_REGISTRY/web:dryrun
docker tag $_AZ_REGISTRY/web:latest $_AZ_REGISTRY/web-sh:dryrun
else
docker tag $_AZ_REGISTRY/web:$_BRANCH_NAME $_AZ_REGISTRY/web:$_RELEASE_VERSION
docker tag $_AZ_REGISTRY/web:$_BRANCH_NAME $_AZ_REGISTRY/web-sh:$_RELEASE_VERSION
docker tag $_AZ_REGISTRY/web:$_BRANCH_NAME $_AZ_REGISTRY/web:latest
docker tag $_AZ_REGISTRY/web:$_BRANCH_NAME $_AZ_REGISTRY/web-sh:latest
fi
- name: Push version
run: |
if [[ "${{ github.event.inputs.release_type }}" == "Dry Run" ]]; then
docker push $_AZ_REGISTRY/web:dryrun
docker push $_AZ_REGISTRY/web-sh:dryrun
else
docker push $_AZ_REGISTRY/web:$_RELEASE_VERSION
docker push $_AZ_REGISTRY/web-sh:$_RELEASE_VERSION
docker push $_AZ_REGISTRY/web:latest
docker push $_AZ_REGISTRY/web-sh:latest
fi
- name: Log out of Docker
run: docker logout
ghpages-deploy:
name: Create Deploy PR for GitHub Pages
runs-on: ubuntu-22.04
needs: setup
env:
_RELEASE_VERSION: ${{ needs.setup.outputs.release_version }}
_TAG_VERSION: ${{ needs.setup.outputs.tag_version }}
_BRANCH: "v${{ needs.setup.outputs.release_version }}-deploy"
steps:
- name: Login to Azure - CI Subscription
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve bot secrets
id: retrieve-bot-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
keyvault: bitwarden-ci
secrets: "github-pat-bitwarden-devops-bot-repo-scope"
- name: Checkout GH pages repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
with:
repository: bitwarden/web-vault-pages
path: ghpages-deployment
token: ${{ steps.retrieve-bot-secrets.outputs.github-pat-bitwarden-devops-bot-repo-scope }}
- name: Download latest cloud asset
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
workflow: build-web.yml
path: assets
workflow_conclusion: success
branch: ${{ github.ref_name }}
artifacts: web-*-cloud-COMMERCIAL.zip
- name: Dry Run - Download latest cloud asset
if: ${{ github.event.inputs.release_type == 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
workflow: build-web.yml
path: assets
workflow_conclusion: success
branch: master
artifacts: web-*-cloud-COMMERCIAL.zip
- name: Unzip build asset
working-directory: assets
run: unzip web-*-cloud-COMMERCIAL.zip
- name: Create new branch
run: |
cd ${{ github.workspace }}/ghpages-deployment
git config user.name = "GitHub Action Bot"
git config user.email = "<>"
git config --global url."https://github.com/".insteadOf ssh://git@github.com/
git config --global url."https://".insteadOf ssh://
git checkout -b ${_BRANCH}
- name: Copy build files
run: |
rm -rf ${{ github.workspace }}/ghpages-deployment/*
cp -Rf ${{ github.workspace }}/assets/build/* ghpages-deployment/
- name: Commit and push changes
working-directory: ghpages-deployment
run: |
git add .
git commit -m "Deploy Web v${_RELEASE_VERSION} to GitHub Pages"
git push --set-upstream origin ${_BRANCH} --force
- name: Create GitHub Pages Deploy PR
working-directory: ghpages-deployment
env:
GITHUB_TOKEN: ${{ steps.retrieve-bot-secrets.outputs.github-pat-bitwarden-devops-bot-repo-scope }}
run: |
if [[ "${{ github.event.inputs.release_type }}" == "Dry Run" ]]; then
gh pr create --title "Deploy v${_RELEASE_VERSION} to GitHub Pages" \
--draft \
--body "Deploying v${_RELEASE_VERSION}" \
--base master \
--head "${_BRANCH}"
else
gh pr create --title "Deploy v${_RELEASE_VERSION} to GitHub Pages" \
--body "Deploying v${_RELEASE_VERSION}" \
--base master \
--head "${_BRANCH}"
fi
release:
name: Create GitHub Release
runs-on: ubuntu-22.04
needs:
- setup
- self-host
- ghpages-deploy
steps:
- name: Create GitHub deployment
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: chrnorm/deployment-action@d42cde7132fcec920de534fffc3be83794335c00 # v2.0.5
id: deployment
with:
token: '${{ secrets.GITHUB_TOKEN }}'
initial-status: 'in_progress'
environment-url: http://vault.bitwarden.com
environment: 'Web Vault - Production'
description: 'Deployment ${{ needs.setup.outputs.release_version }} from branch ${{ github.ref_name }}'
task: release
- name: Download latest build artifacts
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
uses: bitwarden/gh-actions/download-artifacts@main
with:
workflow: build-web.yml
path: apps/web/artifacts
@@ -238,12 +64,12 @@ jobs:
- name: Dry Run - Download latest build artifacts
if: ${{ github.event.inputs.release_type == 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
uses: bitwarden/gh-actions/download-artifacts@main
with:
workflow: build-web.yml
path: apps/web/artifacts
workflow_conclusion: success
branch: master
branch: main
artifacts: "web-*-selfhosted-COMMERCIAL.zip,
web-*-selfhosted-open-source.zip"
@@ -255,7 +81,7 @@ jobs:
- name: Create release
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: ncipollo/release-action@a2e71bdd4e7dab70ca26a852f29600c98b33153e # v1.12.0
uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.0
with:
name: "Web v${{ needs.setup.outputs.release_version }}"
commit: ${{ github.sha }}
@@ -265,21 +91,3 @@ jobs:
apps/web/artifacts/web-${{ needs.setup.outputs.release_version }}-selfhosted-open-source.zip"
token: ${{ secrets.GITHUB_TOKEN }}
draft: true
- name: Update deployment status to Success
if: ${{ github.event.inputs.release_type != 'Dry Run' && success() }}
uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1
with:
token: '${{ secrets.GITHUB_TOKEN }}'
environment-url: http://vault.bitwarden.com
state: 'success'
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
- name: Update deployment status to Failure
if: ${{ github.event.inputs.release_type != 'Dry Run' && failure() }}
uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1
with:
token: '${{ secrets.GITHUB_TOKEN }}'
environment-url: http://vault.bitwarden.com
state: 'failure'
deployment-id: ${{ steps.deployment.outputs.deployment_id }}

View File

@@ -0,0 +1,498 @@
name: Repository management
on:
workflow_dispatch:
inputs:
task:
default: "Version Bump"
description: "Task to execute"
options:
- "Version Bump"
- "Version Bump and Cut rc"
required: true
type: choice
bump_browser:
description: "Bump Browser version?"
type: boolean
default: false
bump_cli:
description: "Bump CLI version?"
type: boolean
default: false
bump_desktop:
description: "Bump Desktop version?"
type: boolean
default: false
bump_web:
description: "Bump Web version?"
type: boolean
default: false
target_ref:
default: "main"
description: "Branch/Tag to target for cut"
required: true
type: string
version_number_override:
description: "New version override (leave blank for automatic calculation, example: '2024.1.0')"
required: false
type: string
jobs:
setup:
name: Setup
runs-on: ubuntu-24.04
outputs:
branch: ${{ steps.set-branch.outputs.branch }}
steps:
- name: Set branch
id: set-branch
env:
TASK: ${{ inputs.task }}
run: |
if [[ "$TASK" == "Version Bump" ]]; then
BRANCH="none"
elif [[ "$TASK" == "Version Bump and Cut rc" ]]; then
BRANCH="rc"
fi
echo "branch=$BRANCH" >> $GITHUB_OUTPUT
cut_branch:
name: Cut branch
if: ${{ needs.setup.outputs.branch == 'rc' }}
needs: setup
runs-on: ubuntu-24.04
steps:
- name: Generate GH App token
uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0
id: app-token
with:
app-id: ${{ secrets.BW_GHAPP_ID }}
private-key: ${{ secrets.BW_GHAPP_KEY }}
- name: Check out target ref
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ inputs.target_ref }}
token: ${{ steps.app-token.outputs.token }}
- name: Check if ${{ needs.setup.outputs.branch }} branch exists
env:
BRANCH_NAME: ${{ needs.setup.outputs.branch }}
run: |
if [[ $(git ls-remote --heads origin $BRANCH_NAME) ]]; then
echo "$BRANCH_NAME already exists! Please delete $BRANCH_NAME before running again." >> $GITHUB_STEP_SUMMARY
exit 1
fi
- name: Cut branch
env:
BRANCH_NAME: ${{ needs.setup.outputs.branch }}
run: |
git switch --quiet --create $BRANCH_NAME
git push --quiet --set-upstream origin $BRANCH_NAME
bump_version:
name: Bump Version
if: ${{ always() }}
runs-on: ubuntu-24.04
needs:
- cut_branch
- setup
outputs:
version_browser: ${{ steps.set-final-version-output.outputs.version_browser }}
version_cli: ${{ steps.set-final-version-output.outputs.version_cli }}
version_desktop: ${{ steps.set-final-version-output.outputs.version_desktop }}
version_web: ${{ steps.set-final-version-output.outputs.version_web }}
steps:
- name: Validate version input format
if: ${{ inputs.version_number_override != '' }}
uses: bitwarden/gh-actions/version-check@main
with:
version: ${{ inputs.version_number_override }}
- name: Generate GH App token
uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0
id: app-token
with:
app-id: ${{ secrets.BW_GHAPP_ID }}
private-key: ${{ secrets.BW_GHAPP_KEY }}
- name: Check out branch
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: main
token: ${{ steps.app-token.outputs.token }}
- name: Configure Git
run: |
git config --local user.email "actions@github.com"
git config --local user.name "Github Actions"
########################
# VERSION BUMP SECTION #
########################
### Browser
- name: Get current Browser version
if: ${{ inputs.bump_browser == true }}
id: current-browser-version
run: |
CURRENT_VERSION=$(cat package.json | jq -r '.version')
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
working-directory: apps/browser
- name: Browser - Verify input version
if: ${{ inputs.bump_browser == true && inputs.version_number_override != '' }}
env:
CURRENT_VERSION: ${{ steps.current-browser-version.outputs.version }}
NEW_VERSION: ${{ inputs.version_number_override }}
run: |
# Error if version has not changed.
if [[ "$NEW_VERSION" == "$CURRENT_VERSION" ]]; then
echo "Version has not changed."
exit 1
fi
# Check if version is newer.
printf '%s\n' "${CURRENT_VERSION}" "${NEW_VERSION}" | sort -C -V
if [ $? -eq 0 ]; then
echo "Version check successful."
else
echo "Version check failed."
exit 1
fi
working-directory: apps/browser
- name: Calculate next Browser release version
if: ${{ inputs.bump_browser == true && inputs.version_number_override == '' }}
id: calculate-next-browser-version
uses: bitwarden/gh-actions/version-next@main
with:
version: ${{ steps.current-browser-version.outputs.version }}
- name: Bump Browser Version - Version Override
if: ${{ inputs.bump_browser == true && inputs.version_number_override != '' }}
id: bump-browser-version-override
env:
VERSION: ${{ inputs.version_number_override }}
run: npm version --workspace=@bitwarden/browser $VERSION
- name: Bump Browser Version - Automatic Calculation
if: ${{ inputs.bump_browser == true && inputs.version_number_override == '' }}
id: bump-browser-version-automatic
env:
VERSION: ${{ steps.calculate-next-browser-version.outputs.version }}
run: npm version --workspace=@bitwarden/browser $VERSION
- name: Bump Browser Version - Manifest - Version Override
if: ${{ inputs.bump_browser == true && inputs.version_number_override != '' }}
uses: bitwarden/gh-actions/version-bump@main
with:
file_path: "apps/browser/src/manifest.json"
version: ${{ inputs.version_number_override }}
- name: Bump Browser Version - Manifest - Automatic Calculation
if: ${{ inputs.bump_browser == true && inputs.version_number_override == '' }}
uses: bitwarden/gh-actions/version-bump@main
with:
file_path: "apps/browser/src/manifest.json"
version: ${{ steps.calculate-next-browser-version.outputs.version }}
- name: Bump Browser Version - Manifest v3 - Version Override
if: ${{ inputs.bump_browser == true && inputs.version_number_override != '' }}
uses: bitwarden/gh-actions/version-bump@main
with:
file_path: "apps/browser/src/manifest.v3.json"
version: ${{ inputs.version_number_override }}
- name: Bump Browser Version - Manifest v3 - Automatic Calculation
if: ${{ inputs.bump_browser == true && inputs.version_number_override == '' }}
uses: bitwarden/gh-actions/version-bump@main
with:
file_path: "apps/browser/src/manifest.v3.json"
version: ${{ steps.calculate-next-browser-version.outputs.version }}
- name: Run Prettier after Browser Version Bump
if: ${{ inputs.bump_browser == true }}
run: |
npm install -g prettier
prettier --write apps/browser/src/manifest.json
prettier --write apps/browser/src/manifest.v3.json
### CLI
- name: Get current CLI version
if: ${{ inputs.bump_cli == true }}
id: current-cli-version
run: |
CURRENT_VERSION=$(cat package.json | jq -r '.version')
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
working-directory: apps/cli
- name: CLI - Verify input version
if: ${{ inputs.bump_cli == true && inputs.version_number_override != '' }}
env:
CURRENT_VERSION: ${{ steps.current-cli-version.outputs.version }}
NEW_VERSION: ${{ inputs.version_number_override }}
run: |
# Error if version has not changed.
if [[ "$NEW_VERSION" == "$CURRENT_VERSION" ]]; then
echo "Version has not changed."
exit 1
fi
# Check if version is newer.
printf '%s\n' "${CURRENT_VERSION}" "${NEW_VERSION}" | sort -C -V
if [ $? -eq 0 ]; then
echo "Version check successful."
else
echo "Version check failed."
exit 1
fi
working-directory: apps/cli
- name: Calculate next CLI release version
if: ${{ inputs.bump_cli == true && inputs.version_number_override == '' }}
id: calculate-next-cli-version
uses: bitwarden/gh-actions/version-next@main
with:
version: ${{ steps.current-cli-version.outputs.version }}
- name: Bump CLI Version - Version Override
if: ${{ inputs.bump_cli == true && inputs.version_number_override != '' }}
id: bump-cli-version-override
env:
VERSION: ${{ inputs.version_number_override }}
run: npm version --workspace=@bitwarden/cli $VERSION
- name: Bump CLI Version - Automatic Calculation
if: ${{ inputs.bump_cli == true && inputs.version_number_override == '' }}
id: bump-cli-version-automatic
env:
VERSION: ${{ steps.calculate-next-cli-version.outputs.version }}
run: npm version --workspace=@bitwarden/cli $VERSION
### Desktop
- name: Get current Desktop version
if: ${{ inputs.bump_desktop == true }}
id: current-desktop-version
run: |
CURRENT_VERSION=$(cat package.json | jq -r '.version')
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
working-directory: apps/desktop
- name: Desktop - Verify input version
if: ${{ inputs.bump_desktop == true && inputs.version_number_override != '' }}
env:
CURRENT_VERSION: ${{ steps.current-desktop-version.outputs.version }}
NEW_VERSION: ${{ inputs.version_number_override }}
run: |
# Error if version has not changed.
if [[ "$NEW_VERSION" == "$CURRENT_VERSION" ]]; then
echo "Version has not changed."
exit 1
fi
# Check if version is newer.
printf '%s\n' "${CURRENT_VERSION}" "${NEW_VERSION}" | sort -C -V
if [ $? -eq 0 ]; then
echo "Version check successful."
else
echo "Version check failed."
exit 1
fi
working-directory: apps/desktop
- name: Calculate next Desktop release version
if: ${{ inputs.bump_desktop == true && inputs.version_number_override == '' }}
id: calculate-next-desktop-version
uses: bitwarden/gh-actions/version-next@main
with:
version: ${{ steps.current-desktop-version.outputs.version }}
- name: Bump Desktop Version - Root - Version Override
if: ${{ inputs.bump_desktop == true && inputs.version_number_override != '' }}
id: bump-desktop-version-override
env:
VERSION: ${{ inputs.version_number_override }}
run: npm version --workspace=@bitwarden/desktop $VERSION
- name: Bump Desktop Version - Root - Automatic Calculation
if: ${{ inputs.bump_desktop == true && inputs.version_number_override == '' }}
id: bump-desktop-version-automatic
env:
VERSION: ${{ steps.calculate-next-desktop-version.outputs.version }}
run: npm version --workspace=@bitwarden/desktop $VERSION
- name: Bump Desktop Version - App - Version Override
if: ${{ inputs.bump_desktop == true && inputs.version_number_override != '' }}
env:
VERSION: ${{ inputs.version_number_override }}
run: npm version $VERSION
working-directory: "apps/desktop/src"
- name: Bump Desktop Version - App - Automatic Calculation
if: ${{ inputs.bump_desktop == true && inputs.version_number_override == '' }}
env:
VERSION: ${{ steps.calculate-next-desktop-version.outputs.version }}
run: npm version $VERSION
working-directory: "apps/desktop/src"
### Web
- name: Get current Web version
if: ${{ inputs.bump_web == true }}
id: current-web-version
run: |
CURRENT_VERSION=$(cat package.json | jq -r '.version')
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
working-directory: apps/web
- name: Web - Verify input version
if: ${{ inputs.bump_web == true && inputs.version_number_override != '' }}
env:
CURRENT_VERSION: ${{ steps.current-web-version.outputs.version }}
NEW_VERSION: ${{ inputs.version_number_override }}
run: |
# Error if version has not changed.
if [[ "$NEW_VERSION" == "$CURRENT_VERSION" ]]; then
echo "Version has not changed."
exit 1
fi
# Check if version is newer.
printf '%s\n' "${CURRENT_VERSION}" "${NEW_VERSION}" | sort -C -V
if [ $? -eq 0 ]; then
echo "Version check successful."
else
echo "Version check failed."
exit 1
fi
working-directory: apps/web
- name: Calculate next Web release version
if: ${{ inputs.bump_web == true && inputs.version_number_override == '' }}
id: calculate-next-web-version
uses: bitwarden/gh-actions/version-next@main
with:
version: ${{ steps.current-web-version.outputs.version }}
- name: Bump Web Version - Version Override
if: ${{ inputs.bump_web == true && inputs.version_number_override != '' }}
id: bump-web-version-override
env:
VERSION: ${{ inputs.version_number_override }}
run: npm version --workspace=@bitwarden/web-vault $VERSION
- name: Bump Web Version - Automatic Calculation
if: ${{ inputs.bump_web == true && inputs.version_number_override == '' }}
id: bump-web-version-automatic
env:
VERSION: ${{ steps.calculate-next-web-version.outputs.version }}
run: npm version --workspace=@bitwarden/web-vault $VERSION
########################
- name: Set final version output
id: set-final-version-output
env:
VERSION: ${{ inputs.version_number_override }}
run: |
if [[ "${{ steps.bump-browser-version-override.outcome }}" = "success" ]]; then
echo "version_browser=$VERSION" >> $GITHUB_OUTPUT
elif [[ "${{ steps.bump-browser-version-automatic.outcome }}" = "success" ]]; then
echo "version_browser=${{ steps.calculate-next-browser-version.outputs.version }}" >> $GITHUB_OUTPUT
fi
if [[ "${{ steps.bump-cli-version-override.outcome }}" = "success" ]]; then
echo "version_cli=$VERSION" >> $GITHUB_OUTPUT
elif [[ "${{ steps.bump-cli-version-automatic.outcome }}" = "success" ]]; then
echo "version_cli=${{ steps.calculate-next-cli-version.outputs.version }}" >> $GITHUB_OUTPUT
fi
if [[ "${{ steps.bump-desktop-version-override.outcome }}" = "success" ]]; then
echo "version_desktop=$VERSION" >> $GITHUB_OUTPUT
elif [[ "${{ steps.bump-desktop-version-automatic.outcome }}" = "success" ]]; then
echo "version_desktop=${{ steps.calculate-next-desktop-version.outputs.version }}" >> $GITHUB_OUTPUT
fi
if [[ "${{ steps.bump-web-version-override.outcome }}" = "success" ]]; then
echo "version_web=$VERSION" >> $GITHUB_OUTPUT
elif [[ "${{ steps.bump-web-version-automatic.outcome }}" = "success" ]]; then
echo "version_web=${{ steps.calculate-next-web-version.outputs.version }}" >> $GITHUB_OUTPUT
fi
- 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 "Bumped client version(s)" -a
- name: Push changes
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }}
run: git push
cherry_pick:
name: Cherry-Pick Commit(s)
if: ${{ needs.setup.outputs.branch == 'rc' }}
runs-on: ubuntu-24.04
needs:
- bump_version
- setup
steps:
- name: Generate GH App token
uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0
id: app-token
with:
app-id: ${{ secrets.BW_GHAPP_ID }}
private-key: ${{ secrets.BW_GHAPP_KEY }}
- name: Check out main branch
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: main
token: ${{ steps.app-token.outputs.token }}
- name: Configure Git
run: |
git config --local user.email "actions@github.com"
git config --local user.name "Github Actions"
- name: Perform cherry-pick(s)
run: |
# Function for cherry-picking
cherry_pick () {
local package_path="apps/$1/package.json"
local source_branch=$2
local destination_branch=$3
# Get project commit/version from source branch
git switch $source_branch
SOURCE_COMMIT=$(git log --reverse --pretty=format:"%H" --max-count=1 $package_path)
SOURCE_VERSION=$(cat $package_path | jq -r '.version')
# Get project commit/version from destination branch
git switch $destination_branch
DESTINATION_VERSION=$(cat $package_path | jq -r '.version')
if [[ "$DESTINATION_VERSION" != "$SOURCE_VERSION" ]]; then
git cherry-pick --strategy-option=theirs -x $SOURCE_COMMIT
git push -u origin $destination_branch
fi
# Cherry-pick from 'main' into 'rc'
cherry_pick browser main rc
cherry_pick cli main rc
cherry_pick desktop main rc
cherry_pick web main rc

View File

@@ -0,0 +1,41 @@
name: Retrieve Current Desktop Rollout
on:
workflow_dispatch:
defaults:
run:
shell: bash
jobs:
rollout:
name: Retrieve Rollout Percentage
runs-on: ubuntu-22.04
steps:
- name: Login to Azure
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "aws-electron-access-id,
aws-electron-access-key,
aws-electron-bucket-name"
- name: Download channel update info files from S3
env:
AWS_ACCESS_KEY_ID: ${{ steps.retrieve-secrets.outputs.aws-electron-access-id }}
AWS_SECRET_ACCESS_KEY: ${{ steps.retrieve-secrets.outputs.aws-electron-access-key }}
AWS_DEFAULT_REGION: 'us-west-2'
AWS_S3_BUCKET_NAME: ${{ steps.retrieve-secrets.outputs.aws-electron-bucket-name }}
run: aws s3 cp $AWS_S3_BUCKET_NAME/desktop/latest.yml . --quiet
- name: Get current rollout percentage
run: |
CURRENT_PCT=$(sed -r -n "s/stagingPercentage:\s([0-9]+)/\1/p" latest.yml)
CURRENT_VERSION=$(sed -r -n "s/version:\s(.*)/\1/p" latest.yml)
echo "Desktop ${CURRENT_VERSION} rollout percentage is ${CURRENT_PCT}%" >> $GITHUB_STEP_SUMMARY

80
.github/workflows/scan.yml vendored Normal file
View File

@@ -0,0 +1,80 @@
name: Scan
on:
workflow_dispatch:
push:
branches:
- "main"
- "rc"
- "hotfix-rc"
pull_request_target:
types: [opened, synchronize]
jobs:
check-run:
name: Check PR run
uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main
sast:
name: SAST scan
runs-on: ubuntu-22.04
needs: check-run
permissions:
contents: read
pull-requests: write
security-events: write
steps:
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Scan with Checkmarx
uses: checkmarx/ast-github-action@f0869bd1a37fddc06499a096101e6c900e815d81 # 2.0.36
env:
INCREMENTAL: "${{ contains(github.event_name, 'pull_request') && '--sast-incremental' || '' }}"
with:
project_name: ${{ github.repository }}
cx_tenant: ${{ secrets.CHECKMARX_TENANT }}
base_uri: https://ast.checkmarx.net/
cx_client_id: ${{ secrets.CHECKMARX_CLIENT_ID }}
cx_client_secret: ${{ secrets.CHECKMARX_SECRET }}
additional_params: |
--report-format sarif \
--filter "state=TO_VERIFY;PROPOSED_NOT_EXPLOITABLE;CONFIRMED;URGENT" \
--output-path . ${{ env.INCREMENTAL }}
- name: Upload Checkmarx results to GitHub
uses: github/codeql-action/upload-sarif@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0
with:
sarif_file: cx_result.sarif
quality:
name: Quality scan
runs-on: ubuntu-22.04
needs: check-run
permissions:
contents: read
pull-requests: write
steps:
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Scan with SonarCloud
uses: sonarsource/sonarcloud-github-action@383f7e52eae3ab0510c3cb0e7d9d150bbaeab838 # v3.1.0
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
args: >
-Dsonar.organization=${{ github.repository_owner }}
-Dsonar.projectKey=${{ github.repository_owner }}_${{ github.event.repository.name }}
-Dsonar.tests=.
-Dsonar.sources=.
-Dsonar.test.inclusions=**/*.spec.ts
-Dsonar.exclusions=**/*.spec.ts

View File

@@ -1,4 +1,3 @@
---
name: Staged Rollout Desktop
on:
@@ -20,40 +19,32 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Login to Azure
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "aws-electron-access-id,
aws-electron-access-key,
aws-electron-bucket-name,
r2-electron-access-id,
r2-electron-access-key,
r2-electron-bucket-name,
cf-prod-account"
aws-electron-bucket-name"
- name: Download channel update info files from R2
- name: Download channel update info files from S3
env:
AWS_ACCESS_KEY_ID: ${{ steps.retrieve-secrets.outputs.r2-electron-access-id }}
AWS_SECRET_ACCESS_KEY: ${{ steps.retrieve-secrets.outputs.r2-electron-access-key }}
AWS_DEFAULT_REGION: 'us-east-1'
AWS_S3_BUCKET_NAME: ${{ steps.retrieve-secrets.outputs.r2-electron-bucket-name }}
CF_ACCOUNT: ${{ steps.retrieve-secrets.outputs.cf-prod-account }}
AWS_ACCESS_KEY_ID: ${{ steps.retrieve-secrets.outputs.aws-electron-access-id }}
AWS_SECRET_ACCESS_KEY: ${{ steps.retrieve-secrets.outputs.aws-electron-access-key }}
AWS_DEFAULT_REGION: 'us-west-2'
AWS_S3_BUCKET_NAME: ${{ steps.retrieve-secrets.outputs.aws-electron-bucket-name }}
run: |
aws s3 cp $AWS_S3_BUCKET_NAME/desktop/latest.yml . \
--quiet \
--endpoint-url https://${CF_ACCOUNT}.r2.cloudflarestorage.com
--quiet
aws s3 cp $AWS_S3_BUCKET_NAME/desktop/latest-linux.yml . \
--quiet \
--endpoint-url https://${CF_ACCOUNT}.r2.cloudflarestorage.com
--quiet
aws s3 cp $AWS_S3_BUCKET_NAME/desktop/latest-mac.yml . \
--quiet \
--endpoint-url https://${CF_ACCOUNT}.r2.cloudflarestorage.com
--quiet
- name: Check new rollout percentage
env:
@@ -95,20 +86,3 @@ jobs:
aws s3 cp latest-mac.yml $AWS_S3_BUCKET_NAME/desktop/ \
--acl "public-read"
- name: Publish channel update info files to R2
env:
AWS_ACCESS_KEY_ID: ${{ steps.retrieve-secrets.outputs.r2-electron-access-id }}
AWS_SECRET_ACCESS_KEY: ${{ steps.retrieve-secrets.outputs.r2-electron-access-key }}
AWS_DEFAULT_REGION: 'us-east-1'
AWS_S3_BUCKET_NAME: ${{ steps.retrieve-secrets.outputs.r2-electron-bucket-name }}
CF_ACCOUNT: ${{ steps.retrieve-secrets.outputs.cf-prod-account }}
run: |
aws s3 cp latest.yml $AWS_S3_BUCKET_NAME/desktop/ \
--endpoint-url https://${CF_ACCOUNT}.r2.cloudflarestorage.com
aws s3 cp latest-linux.yml $AWS_S3_BUCKET_NAME/desktop/ \
--endpoint-url https://${CF_ACCOUNT}.r2.cloudflarestorage.com
aws s3 cp latest-mac.yml $AWS_S3_BUCKET_NAME/desktop/ \
--endpoint-url https://${CF_ACCOUNT}.r2.cloudflarestorage.com

View File

@@ -1,4 +1,3 @@
---
name: 'Close stale issues and PRs'
on:
workflow_dispatch:
@@ -8,10 +7,10 @@ on:
jobs:
stale:
name: 'Check for stale issues and PRs'
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- name: 'Run stale action'
uses: actions/stale@1160a2240286f5da8ec72b1c0816ce2481aabf84 # v8.0.0
uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # v9.0.0
with:
stale-issue-label: 'needs-reply'
stale-pr-label: 'needs-changes'
@@ -27,4 +26,4 @@ jobs:
If youre still working on this, please respond here after youve made the changes weve requested and our team will re-open it for further review.
Please make sure to resolve any conflicts with the master branch before requesting another review.
Please make sure to resolve any conflicts with the main branch before requesting another review.

View File

@@ -1,38 +1,60 @@
---
name: Run tests
name: Testing
on:
workflow_dispatch:
push:
branches:
- "main"
- "rc"
- "hotfix-rc-*"
pull_request:
branches-ignore:
- 'l10n_master'
- 'cf-pages'
paths:
- 'apps/**'
- 'libs/**'
- '*'
- '!*.md'
- '!*.txt'
- '.github/workflows/test.yml'
defaults:
run:
shell: bash
types: [opened, synchronize]
jobs:
test:
check-test-secrets:
name: Check for test secrets
runs-on: ubuntu-22.04
outputs:
available: ${{ steps.check-test-secrets.outputs.available }}
permissions:
contents: read
steps:
- name: Check
id: check-test-secrets
run: |
if [ "${{ secrets.CODECOV_TOKEN }}" != '' ]; then
echo "available=true" >> $GITHUB_OUTPUT;
else
echo "available=false" >> $GITHUB_OUTPUT;
fi
testing:
name: Run tests
runs-on: ubuntu-22.04
needs: check-test-secrets
permissions:
checks: write
contents: read
pull-requests: write
steps:
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Get Node Version
id: retrieve-node-version
run: |
NODE_NVMRC=$(cat .nvmrc)
NODE_VERSION=${NODE_NVMRC/v/''}
echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT
- name: Set up Node
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
node-version: '18'
node-version: ${{ steps.retrieve-node-version.outputs.node_version }}
- name: Print environment
run: |
@@ -49,30 +71,46 @@ jobs:
run: npm run test:types
- name: Run tests
run: npm run test
# maxWorkers is a workaround for a memory leak that crashes tests in CI:
# https://github.com/facebook/jest/issues/9430#issuecomment-1149882002
run: npm test -- --coverage --maxWorkers=3
- name: Report test results
uses: dorny/test-reporter@c9b3d0e2bd2a4e96aaf424dbaa31c46b42318226 # v1.6.0
if: always()
uses: dorny/test-reporter@31a54ee7ebcacc03a09ea97a7e5465a47b84aea5 # v1.9.1
if: ${{ needs.check-test-secrets.outputs.available == 'true' && !cancelled() }}
with:
name: Test Results
path: "junit.xml"
reporter: jest-junit
fail-on-error: true
- name: Upload coverage to codecov.io
uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0
if: ${{ needs.check-test-secrets.outputs.available == 'true' }}
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- name: Upload results to codecov.io
uses: codecov/test-results-action@9739113ad922ea0a9abb4b2c0f8bf6a4aa8ef820 # v1.0.1
if: ${{ needs.check-test-secrets.outputs.available == 'true' }}
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
rust:
name: rust - ${{ matrix.os }}
runs-on: ${{ matrix.os || 'ubuntu-latest' }}
name: Run Rust tests on ${{ matrix.os }}
runs-on: ${{ matrix.os || 'ubuntu-22.04' }}
permissions:
contents: read
strategy:
matrix:
os:
- ubuntu-latest
- ubuntu-22.04
- macos-latest
- windows-latest
steps:
- name: Rust version check
- name: Check Rust version
run: rustup --version
- name: Install gnome-keyring
@@ -81,8 +119,8 @@ jobs:
sudo apt-get update
sudo apt-get install -y gnome-keyring dbus-x11
- name: Checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Build
working-directory: ./apps/desktop/desktop_native
@@ -99,7 +137,12 @@ jobs:
eval "$(printf '\n' | /usr/bin/gnome-keyring-daemon --start)"
cargo test -- --test-threads=1
- name: Test Windows / macOS
if: ${{ matrix.os!='ubuntu-latest' }}
- name: Test macOS
if: ${{ matrix.os=='macos-latest' }}
working-directory: ./apps/desktop/desktop_native
run: cargo test -- --test-threads=1
- name: Test Windows
if: ${{ matrix.os=='windows-latest'}}
working-directory: ./apps/desktop/desktop_native/core
run: cargo test -- --test-threads=1

View File

@@ -1,48 +1,62 @@
---
name: Version Auto Bump
name: Auto Bump Desktop Version
on:
push:
tags:
- desktop-v**
defaults:
run:
shell: bash
jobs:
setup:
name: "Setup"
runs-on: ubuntu-22.04
outputs:
version_number: ${{ steps.version.outputs.new-version }}
bump-version:
name: Bump Desktop Version
runs-on: ubuntu-24.04
steps:
- name: Checkout Branch
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Generate GH App token
uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0
id: app-token
with:
app-id: ${{ secrets.BW_GHAPP_ID }}
private-key: ${{ secrets.BW_GHAPP_KEY }}
- name: Calculate bumped version
id: version
env:
RELEASE_TAG: ${{ github.ref }}
- name: Check out target ref
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: main
token: ${{ steps.app-token.outputs.token }}
- name: Configure Git
run: |
CURR_MAJOR=$(echo $RELEASE_TAG | sed -r 's/refs\/tags\/[a-z]*-v([0-9]{4}\.[0-9]{1,2})\.([0-9]{1,2})/\1/')
CURR_PATCH=$(echo $RELEASE_TAG | sed -r 's/refs\/tags\/[a-z]*-v([0-9]{4}\.[0-9]{1,2})\.([0-9]{1,2})/\2/')
echo "Current Major: $CURR_MAJOR"
echo "Current Patch: $CURR_PATCH"
git config --local user.email "actions@github.com"
git config --local user.name "Github Actions"
NEW_PATCH=$((CURR_PATCH+1))
- name: Get current Desktop version
id: current-desktop-version
run: |
CURRENT_VERSION=$(cat package.json | jq -r '.version')
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
working-directory: apps/desktop
echo "New patch: $NEW_PATCH"
- name: Calculate next Desktop release version
id: calculate-next-desktop-version
uses: bitwarden/gh-actions/version-next@main
with:
version: ${{ steps.current-desktop-version.outputs.version }}
NEW_VER=$CURR_MAJOR.$NEW_PATCH
echo "New Version: $NEW_VER"
echo "new-version=$NEW_VER" >> $GITHUB_OUTPUT
- name: Bump Desktop Version - Root - Automatic Calculation
id: bump-desktop-version-automatic
env:
VERSION: ${{ steps.calculate-next-desktop-version.outputs.version }}
run: npm version --workspace=@bitwarden/desktop $VERSION
trigger_version_bump:
name: Bump version to ${{ needs.setup.outputs.version_number }}
needs: setup
uses: ./.github/workflows/version-bump.yml
with:
version_number: ${{ needs.setup.outputs.version_number }}
bump_desktop: true
secrets: inherit
- name: Bump Desktop Version - App - Automatic Calculation
env:
VERSION: ${{ steps.calculate-next-desktop-version.outputs.version }}
run: npm version $VERSION
working-directory: "apps/desktop/src"
- name: Commit files
env:
VERSION: ${{ steps.calculate-next-desktop-version.outputs.version }}
run: git commit -m "Bumped Desktop client to $VERSION" -a
- name: Push changes
run: git push

View File

@@ -1,287 +0,0 @@
---
name: Version Bump
run-name: Version Bump - ${{ github.ref_name }}
on:
workflow_dispatch:
inputs:
bump_browser:
description: "Browser Project Version Bump"
type: boolean
default: false
bump_cli:
description: "CLI Project Version Bump"
type: boolean
default: false
bump_desktop:
description: "Desktop Project Version Bump"
type: boolean
default: false
bump_web:
description: "Web Project Version Bump"
type: boolean
default: false
version_number:
description: "New Version"
required: true
workflow_call:
inputs:
version_number:
required: true
type: string
bump_desktop:
description: "Desktop Project Version Bump"
type: boolean
default: false
defaults:
run:
shell: bash
jobs:
bump_version:
name: "Bump Version"
runs-on: ubuntu-22.04
steps:
- name: Checkout Branch
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Login to Azure - Prod Subscription
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
keyvault: "bitwarden-ci"
secrets: "github-gpg-private-key, github-gpg-private-key-passphrase"
- name: Import GPG key
uses: crazy-max/ghaction-import-gpg@72b6676b71ab476b77e676928516f6982eef7a41 # v5.3.0
with:
gpg_private_key: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key }}
passphrase: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key-passphrase }}
git_user_signingkey: true
git_commit_gpgsign: true
- name: Create Version Branch
id: branch
env:
VERSION: ${{ inputs.version_number }}
run: |
CLIENTS=()
if [[ ${{ inputs.bump_browser }} == true ]]; then
CLIENTS+=("browser")
fi
if [[ ${{ inputs.bump_cli }} == true ]]; then
CLIENTS+=("cli")
fi
if [[ ${{ inputs.bump_desktop }} == true ]]; then
CLIENTS+=("desktop")
fi
if [[ ${{ inputs.bump_web }} == true ]]; then
CLIENTS+=("web")
fi
printf -v joined '%s,' "${CLIENTS[@]}"
echo "client=${joined%,}" >> $GITHUB_OUTPUT
BRANCH=version_bump_${VERSION}_${GITHUB_SHA:0:7}
echo "branch=$BRANCH" >> $GITHUB_OUTPUT
git switch -c ${BRANCH}
########################
# VERSION BUMP SECTION #
########################
### Browser
- name: Browser - Verify input version
if: ${{ inputs.bump_browser == true }}
env:
NEW_VERSION: ${{ inputs.version_number }}
run: |
CURRENT_VERSION=$(cat package.json | jq -r '.version')
# Error if version has not changed.
if [[ "$NEW_VERSION" == "$CURRENT_VERSION" ]]; then
echo "Version has not changed."
exit 1
fi
# Check if version is newer.
printf '%s\n' "${CURRENT_VERSION}" "${NEW_VERSION}" | sort -C -V
if [ $? -eq 0 ]; then
echo "Version check successful."
fi
working-directory: apps/browser
- name: Bump Browser Version
if: ${{ inputs.bump_browser == true }}
env:
VERSION: ${{ inputs.version_number }}
run: npm version --workspace=@bitwarden/browser ${VERSION}
- name: Bump Browser Version - Manifest
if: ${{ inputs.bump_browser == true }}
uses: bitwarden/gh-actions/version-bump@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
version: ${{ inputs.version_number }}
file_path: "apps/browser/src/manifest.json"
- name: Bump Browser Version - Manifest v3
if: ${{ inputs.bump_browser == true }}
uses: bitwarden/gh-actions/version-bump@62d1bf7c3e31c458cc7236b1e69a475d235cd78f
with:
version: ${{ inputs.version_number }}
file_path: "apps/browser/src/manifest.v3.json"
- name: Run Prettier after Browser Version Bump
if: ${{ inputs.bump_browser == true }}
run: |
npm install -g prettier
prettier --write apps/browser/src/manifest.json
prettier --write apps/browser/src/manifest.v3.json
### CLI
- name: CLI - Verify input version
if: ${{ inputs.bump_cli == true }}
env:
NEW_VERSION: ${{ inputs.version_number }}
run: |
CURRENT_VERSION=$(cat package.json | jq -r '.version')
# Error if version has not changed.
if [[ "$NEW_VERSION" == "$CURRENT_VERSION" ]]; then
echo "Version has not changed."
exit 1
fi
# Check if version is newer.
printf '%s\n' "${CURRENT_VERSION}" "${NEW_VERSION}" | sort -C -V
if [ $? -eq 0 ]; then
echo "Version check successful."
fi
working-directory: apps/cli
- name: Bump CLI Version
if: ${{ inputs.bump_cli == true }}
env:
VERSION: ${{ inputs.version_number }}
run: npm version --workspace=@bitwarden/cli ${VERSION}
### Desktop
- name: Desktop - Verify input version
if: ${{ inputs.bump_desktop == true }}
env:
NEW_VERSION: ${{ inputs.version_number }}
run: |
CURRENT_VERSION=$(cat package.json | jq -r '.version')
# Error if version has not changed.
if [[ "$NEW_VERSION" == "$CURRENT_VERSION" ]]; then
echo "Version has not changed."
exit 1
fi
# Check if version is newer.
printf '%s\n' "${CURRENT_VERSION}" "${NEW_VERSION}" | sort -C -V
if [ $? -eq 0 ]; then
echo "Version check successful."
fi
working-directory: apps/desktop
- name: Bump Desktop Version - Root
if: ${{ inputs.bump_desktop == true }}
env:
VERSION: ${{ inputs.version_number }}
run: npm version --workspace=@bitwarden/desktop ${VERSION}
- name: Bump Desktop Version - App
if: ${{ inputs.bump_desktop == true }}
env:
VERSION: ${{ inputs.version_number }}
run: npm version ${VERSION}
working-directory: "apps/desktop/src"
### Web
- name: Web - Verify input version
if: ${{ inputs.bump_web == true }}
env:
NEW_VERSION: ${{ inputs.version_number }}
run: |
CURRENT_VERSION=$(cat package.json | jq -r '.version')
# Error if version has not changed.
if [[ "$NEW_VERSION" == "$CURRENT_VERSION" ]]; then
echo "Version has not changed."
exit 1
fi
# Check if version is newer.
printf '%s\n' "${CURRENT_VERSION}" "${NEW_VERSION}" | sort -C -V
if [ $? -eq 0 ]; then
echo "Version check successful."
fi
working-directory: apps/web
- name: Bump Web Version
if: ${{ inputs.bump_web == true }}
env:
VERSION: ${{ inputs.version_number }}
run: npm version --workspace=@bitwarden/web-vault ${VERSION}
########################
- name: Setup git
run: |
git config --local user.email "106330231+bitwarden-devops-bot@users.noreply.github.com"
git config --local user.name "bitwarden-devops-bot"
- 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' }}
env:
CLIENT: ${{ steps.branch.outputs.client }}
VERSION: ${{ inputs.version_number }}
run: git commit -m "Bumped ${CLIENT} version to ${VERSION}" -a
- name: Push changes
if: ${{ (github.ref == 'refs/heads/master') && (steps.version-changed.outputs.changes_to_commit == 'TRUE') }}
env:
BRANCH: ${{ steps.branch.outputs.branch }}
run: git push -u origin ${BRANCH}
- name: Create Bump Version PR
if: ${{ (github.ref == 'refs/heads/master') && (steps.version-changed.outputs.changes_to_commit == 'TRUE') }}
env:
BASE_BRANCH: master
BRANCH: ${{ steps.branch.outputs.branch }}
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
TITLE: "Bump ${{ steps.branch.outputs.client }} version to ${{ inputs.version_number }}"
run: |
gh pr create --title "$TITLE" \
--base "$BASE_BRANCH" \
--head "$BRANCH" \
--label "version update" \
--label "automated pr" \
--body "
## Type of change
- [ ] Bug fix
- [ ] New feature development
- [ ] Tech debt (refactoring, code cleanup, dependency upgrades, etc)
- [ ] Build/deploy pipeline (DevOps)
- [X] Other
## Objective
Automated ${{ steps.branch.outputs.client }} version bump to ${{ inputs.version_number }}"

View File

@@ -1,11 +0,0 @@
---
name: Workflow Linter
on:
pull_request:
paths:
- .github/workflows/**
jobs:
call-workflow:
uses: bitwarden/gh-actions/.github/workflows/workflow-linter.yml@62d1bf7c3e31c458cc7236b1e69a475d235cd78f

6
.gitignore vendored
View File

@@ -27,6 +27,9 @@ npm-debug.log
dist
build
.angular/cache
.flatpak
.flatpak-repo
.flatpak-builder
# Testing
coverage
@@ -42,3 +45,6 @@ junit.xml
documentation.json
.eslintcache
storybook-static
# Local app configuration
apps/**/config/local.json

View File

@@ -1,4 +1 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged

2
.nvmrc
View File

@@ -1 +1 @@
v18
v20

View File

@@ -9,7 +9,6 @@ storybook-static
# External libraries / auto synced locales
apps/browser/src/_locales
apps/browser/src/auth/scripts/duo.js
apps/browser/src/autofill/content/autofill.js
apps/browser/src/safari
apps/desktop/src/locales

View File

@@ -1,21 +1,33 @@
import { dirname, join } from "path";
import { StorybookConfig } from "@storybook/angular";
import TsconfigPathsPlugin from "tsconfig-paths-webpack-plugin";
import remarkGfm from "remark-gfm";
const config: StorybookConfig = {
stories: [
"../libs/auth/src/**/*.mdx",
"../libs/auth/src/**/*.stories.@(js|jsx|ts|tsx)",
"../libs/tools/send/send-ui/src/**/*.mdx",
"../libs/tools/send/send-ui/src/**/*.stories.@(js|jsx|ts|tsx)",
"../libs/vault/src/**/*.mdx",
"../libs/vault/src/**/*.stories.@(js|jsx|ts|tsx)",
"../libs/components/src/**/*.mdx",
"../libs/components/src/**/*.stories.@(js|jsx|ts|tsx)",
"../apps/web/src/**/*.mdx",
"../apps/web/src/**/*.stories.@(js|jsx|ts|tsx)",
"../apps/browser/src/**/*.mdx",
"../apps/browser/src/**/*.stories.@(js|jsx|ts|tsx)",
"../bitwarden_license/bit-web/src/**/*.mdx",
"../bitwarden_license/bit-web/src/**/*.stories.@(js|jsx|ts|tsx)",
"../libs/tools/card/src/**/*.mdx",
"../libs/tools/card/src/**/*.stories.@(js|jsx|ts|tsx)",
],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-a11y",
"@storybook/addon-designs",
getAbsolutePath("@storybook/addon-links"),
getAbsolutePath("@storybook/addon-essentials"),
getAbsolutePath("@storybook/addon-a11y"),
getAbsolutePath("@storybook/addon-designs"),
getAbsolutePath("@storybook/addon-interactions"),
{
name: "@storybook/addon-docs",
options: {
@@ -28,7 +40,7 @@ const config: StorybookConfig = {
},
],
framework: {
name: "@storybook/angular",
name: getAbsolutePath("@storybook/angular"),
options: {},
},
core: {
@@ -36,9 +48,7 @@ const config: StorybookConfig = {
},
env: (config) => ({
...config,
FLAGS: JSON.stringify({
secretsManager: true,
}),
FLAGS: JSON.stringify({}),
}),
webpackFinal: async (config, { configType }) => {
if (config.resolve) {
@@ -46,9 +56,12 @@ const config: StorybookConfig = {
}
return config;
},
docs: {
autodocs: true,
},
docs: {},
};
export default config;
// Recommended for mono-repositories
function getAbsolutePath(value: string): any {
return dirname(require.resolve(join(value, "package.json")));
}

63
.storybook/manager.js Normal file
View File

@@ -0,0 +1,63 @@
import { addons } from "@storybook/manager-api";
import { create } from "@storybook/theming/create";
const lightTheme = create({
base: "light",
//logo and Title
brandTitle: "Bitwarden Component Library",
brandUrl: "/",
brandImage:
"https://github.com/bitwarden/brand/blob/51942f8d6e55e96a078a524e0f739efbf1997bcf/logos/logo-horizontal-blue.png?raw=true",
brandTarget: "_self",
//Colors
colorPrimary: "#6D757E",
colorSecondary: "#175DDC",
// UI
appBg: "#f9fBff",
appContentBg: "#ffffff",
appBorderColor: "#CED4DC",
// Text colors
textColor: "#212529",
textInverseColor: "#ffffff",
// Toolbar default and active colors
barTextColor: "#6D757E",
barSelectedColor: "#175DDC",
barBg: "#ffffff",
// Form colors
inputBg: "#ffffff",
inputBorder: "#6D757E",
inputTextColor: "#6D757E",
});
const darkTheme = create({
base: "dark",
//logo and Title
brandTitle: "Bitwarden Component Library",
brandUrl: "/",
brandImage:
"https://github.com/bitwarden/brand/blob/51942f8d6e55e96a078a524e0f739efbf1997bcf/logos/logo-horizontal-white.png?raw=true",
brandTarget: "_self",
//Colors
colorSecondary: "#6A99F0",
barSelectedColor: "#6A99F0",
});
export const getPreferredColorScheme = () => {
if (!globalThis || !globalThis.matchMedia) return "light";
const isDarkThemePreferred = globalThis.matchMedia("(prefers-color-scheme: dark)").matches;
if (isDarkThemePreferred) return "dark";
return "light";
};
addons.setConfig({
theme: getPreferredColorScheme() === "dark" ? darkTheme : lightTheme,
});

View File

@@ -48,7 +48,7 @@ const decorator = componentWrapperDecorator(
},
({ globals }) => {
return { theme: `${globals["theme"]}` };
}
},
);
const preview: Preview = {
@@ -92,7 +92,6 @@ const preview: Preview = {
},
},
parameters: {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
@@ -107,6 +106,7 @@ const preview: Preview = {
},
docs: { source: { type: "dynamic", excludeDecorators: true } },
},
tags: ["autodocs"],
};
export default preview;

View File

@@ -1,12 +1,10 @@
{
"extends": "../tsconfig",
"compilerOptions": {
"types": ["node", "jest", "chrome"],
"allowSyntheticDefaultImports": true
},
"exclude": ["../src/test.setup.ts", "../apps/src/**/*.spec.ts", "../libs/**/*.spec.ts"],
"exclude": ["../src/test.setup.ts", "../apps/**/*.spec.ts", "../libs/**/*.spec.ts"],
"files": [
"./typings.d.ts",
"./preview.tsx",
"../libs/components/src/main.ts",
"../libs/components/src/polyfills.ts"

View File

@@ -1,4 +0,0 @@
declare module "*.md" {
const content: string;
export default content;
}

View File

@@ -5,5 +5,6 @@
"**/locales/*[^n]/messages.json": true,
"**/_locales/[^e]*/messages.json": true,
"**/_locales/*[^n]/messages.json": true
}
},
"rust-analyzer.linkedProjects": ["apps/desktop/desktop_native/Cargo.toml"]
}

View File

@@ -1,22 +1,12 @@
<p align="center">
<img src="https://raw.githubusercontent.com/bitwarden/brand/master/screenshots/apps-combo-logo.png" alt="Bitwarden" />
<img src="https://raw.githubusercontent.com/bitwarden/brand/main/screenshots/apps-combo-logo.png" alt="Bitwarden" />
</p>
<p align="center">
<a href="https://github.com/bitwarden/clients/actions/workflows/build-browser.yml?query=branch:master" target="_blank">
<img src="https://github.com/bitwarden/clients/actions/workflows/build-browser.yml/badge.svg?branch=master" alt="Github Workflow browser build on master" />
</a>
<a href="https://github.com/bitwarden/clients/actions/workflows/build-cli.yml?query=branch:master" target="_blank">
<img src="https://github.com/bitwarden/clients/actions/workflows/build-cli.yml/badge.svg?branch=master" alt="Github Workflow CLI build on master" />
</a>
<a href="https://github.com/bitwarden/clients/actions/workflows/build-desktop.yml?query=branch:master" target="_blank">
<img src="https://github.com/bitwarden/clients/actions/workflows/build-desktop.yml/badge.svg?branch=master" alt="Github Workflow desktop build on master" />
</a>
<a href="https://github.com/bitwarden/clients/actions/workflows/build-web.yml?query=branch:master" target="_blank">
<img src="https://github.com/bitwarden/clients/actions/workflows/build-web.yml/badge.svg?branch=master" alt="Github Workflow web build on master" />
</a>
<a href="https://gitter.im/bitwarden/Lobby" target="_blank">
<img src="https://badges.gitter.im/bitwarden/Lobby.svg" alt="gitter chat" />
</a>
<a href="https://github.com/bitwarden/clients/actions/workflows/build-browser.yml?query=branch:main" target="_blank"><img src="https://github.com/bitwarden/clients/actions/workflows/build-browser.yml/badge.svg?branch=main" alt="GitHub Workflow browser build on main" /></a>
<a href="https://github.com/bitwarden/clients/actions/workflows/build-cli.yml?query=branch:main" target="_blank"><img src="https://github.com/bitwarden/clients/actions/workflows/build-cli.yml/badge.svg?branch=main" alt="GitHub Workflow CLI build on main" /></a>
<a href="https://github.com/bitwarden/clients/actions/workflows/build-desktop.yml?query=branch:main" target="_blank"><img src="https://github.com/bitwarden/clients/actions/workflows/build-desktop.yml/badge.svg?branch=main" alt="GitHub Workflow desktop build on main" /></a>
<a href="https://github.com/bitwarden/clients/actions/workflows/build-web.yml?query=branch:main" target="_blank"><img src="https://github.com/bitwarden/clients/actions/workflows/build-web.yml/badge.svg?branch=main" alt="GitHub Workflow web build on main" /></a>
<a href="https://gitter.im/bitwarden/Lobby" target="_blank"><img src="https://badges.gitter.im/bitwarden/Lobby.svg" alt="gitter chat" /></a>
</p>
---
@@ -30,7 +20,8 @@ Please refer to the [Clients section](https://contributing.bitwarden.com/getting
## Related projects:
- [bitwarden/server](https://github.com/bitwarden/server): The core infrastructure backend (API, database, Docker, etc).
- [bitwarden/mobile](https://github.com/bitwarden/mobile): The mobile app vault (iOS and Android).
- [bitwarden/ios](https://github.com/bitwarden/ios): Bitwarden mobile app for iOS.
- [bitwarden/android](https://github.com/bitwarden/android): Bitwarden mobile app for Android.
- [bitwarden/directory-connector](https://github.com/bitwarden/directory-connector): A tool for syncing a directory (AD, LDAP, Azure, G Suite, Okta) to an organization.
# We're Hiring!
@@ -39,6 +30,6 @@ Interested in contributing in a big way? Consider joining our team! We're hiring
# Contribute
Code contributions are welcome! Please commit any pull requests against the `master` branch. Learn more about how to contribute by reading the [Contributing Guidelines](https://contributing.bitwarden.com/contributing/). Check out the [Contributing Documentation](https://contributing.bitwarden.com/) for how to get started with your first contribution.
Code contributions are welcome! Please commit any pull requests against the `main` branch. Learn more about how to contribute by reading the [Contributing Guidelines](https://contributing.bitwarden.com/contributing/). Check out the [Contributing Documentation](https://contributing.bitwarden.com/) for how to get started with your first contribution.
Security audits and feedback are welcome. Please open an issue or email us privately if the report is sensitive in nature. You can read our security policy in the [`SECURITY.md`](SECURITY.md) file.

View File

@@ -128,10 +128,10 @@
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
"browserTarget": "test-storybook:build:production"
"buildTarget": "test-storybook:build:production"
},
"development": {
"browserTarget": "test-storybook:build:development"
"buildTarget": "test-storybook:build:development"
}
},
"defaultConfiguration": "development"
@@ -142,7 +142,15 @@
"configDir": ".storybook",
"browserTarget": "components:build",
"compodoc": true,
"compodocArgs": ["-p", "./tsconfig.json", "-e", "json", "-d", "."],
"compodocArgs": [
"-p",
"./tsconfig.json",
"-e",
"json",
"-d",
".",
"--disableRoutesGraph"
],
"port": 6006
}
},
@@ -152,7 +160,15 @@
"configDir": ".storybook",
"browserTarget": "components:build",
"compodoc": true,
"compodocArgs": ["-e", "json", "-d", "."],
"compodocArgs": [
"-p",
"./tsconfig.json",
"-e",
"json",
"-d",
".",
"--disableRoutesGraph"
],
"outputDir": "storybook-static"
}
}

View File

@@ -0,0 +1,26 @@
{
"env": {
"browser": true,
"webextensions": true
},
"overrides": [
{
"files": ["src/**/*.ts"],
"excludedFiles": [
"src/**/{content,popup,spec}/**/*.ts",
"src/**/autofill/{notification,overlay}/**/*.ts",
"src/**/autofill/**/{autofill-overlay-content,collect-autofill-content,dom-element-visibility,insert-autofill-content}.service.ts",
"src/**/*.spec.ts"
],
"rules": {
"no-restricted-globals": [
"error",
{
"name": "window",
"message": "The `window` object is not available in service workers and may not be available within the background script. Consider using `self`, `globalThis`, or another global property instead."
}
]
}
}
]
}

View File

@@ -1,3 +1,5 @@
config/local.json
# Safari
dist-safari
!src/safari/safari/app/popup/index.html

View File

@@ -4,13 +4,13 @@
# Bitwarden Browser Extension
<a href="https://chrome.google.com/webstore/detail/bitwarden-free-password-m/nngceckbapebfimnlniiiahkandclblb" target="_blank"><img src="https://imgur.com/3C4iKO0.png" width="64" height="64"></a>
<a href="https://chromewebstore.google.com/detail/bitwarden-free-password-m/nngceckbapebfimnlniiiahkandclblb" target="_blank"><img src="https://imgur.com/3C4iKO0.png" width="64" height="64"></a>
<a href="https://addons.mozilla.org/firefox/addon/bitwarden-password-manager/" target="_blank"><img src="https://imgur.com/ihXsdDO.png" width="64" height="64"></a>
<a href="https://microsoftedge.microsoft.com/addons/detail/bitwarden-free-password/jbkfoedolllekgbhcbcoahefnbanhhlh" target="_blank"><img src="https://imgur.com/vMcaXaw.png" width="64" height="64"></a>
<a href="https://addons.opera.com/extensions/details/bitwarden-free-password-manager/" target="_blank"><img src="https://imgur.com/nSJ9htU.png" width="64" height="64"></a>
<a href="https://bitwarden.com/download/" target="_blank"><img src="https://imgur.com/ENbaWUu.png" width="64" height="64"></a>
<a href="https://chrome.google.com/webstore/detail/bitwarden-free-password-m/nngceckbapebfimnlniiiahkandclblb" target="_blank"><img src="https://imgur.com/EuDp4vP.png" width="64" height="64"></a>
<a href="https://chrome.google.com/webstore/detail/bitwarden-free-password-m/nngceckbapebfimnlniiiahkandclblb" target="_blank"><img src="https://imgur.com/z8yjLZ2.png" width="64" height="64"></a>
<a href="https://chromewebstore.google.com/detail/bitwarden-free-password-m/nngceckbapebfimnlniiiahkandclblb" target="_blank"><img src="https://imgur.com/EuDp4vP.png" width="64" height="64"></a>
<a href="https://chromewebstore.google.com/detail/bitwarden-free-password-m/nngceckbapebfimnlniiiahkandclblb" target="_blank"><img src="https://imgur.com/z8yjLZ2.png" width="64" height="64"></a>
<a href="https://addons.mozilla.org/firefox/addon/bitwarden-password-manager/" target="_blank"><img src="https://imgur.com/MQYBSrD.png" width="64" height="64"></a>
The Bitwarden browser extension is written using the Web Extension API and Angular.

View File

@@ -1,6 +1,7 @@
{
"dev_flags": {},
"devFlags": {},
"flags": {
"showPasswordless": true
"accountSwitching": false,
"sdk": true
}
}

View File

@@ -1,11 +1,11 @@
{
"devFlags": {
"storeSessionDecrypted": false,
"managedEnvironment": {
"base": "https://localhost:8080"
}
},
"skipWelcomeOnInstall": true
},
"flags": {
"showPasswordless": true
"accountSwitching": true
}
}

View File

@@ -1,3 +1,5 @@
{
"flags": {}
"flags": {
"accountSwitching": true
}
}

View File

@@ -1,236 +0,0 @@
const child = require("child_process");
const fs = require("fs");
const del = require("del");
const gulp = require("gulp");
const filter = require("gulp-filter");
const gulpif = require("gulp-if");
const jeditor = require("gulp-json-editor");
const replace = require("gulp-replace");
const zip = require("gulp-zip");
const manifest = require("./src/manifest.json");
const paths = {
build: "./build/",
dist: "./dist/",
coverage: "./coverage/",
node_modules: "./node_modules/",
popupDir: "./src/popup/",
cssDir: "./src/popup/css/",
safari: "./src/safari/",
};
const filters = {
fonts: [
"!build/popup/fonts/*",
"build/popup/fonts/Open_Sans*.woff",
"build/popup/fonts/bwi-font.woff2",
"build/popup/fonts/bwi-font.woff",
"build/popup/fonts/bwi-font.ttf",
],
safari: ["!build/safari/**/*"],
};
function buildString() {
var build = "";
if (process.env.MANIFEST_VERSION) {
build = `-mv${process.env.MANIFEST_VERSION}`;
}
if (process.env.BUILD_NUMBER && process.env.BUILD_NUMBER !== "") {
build = `-${process.env.BUILD_NUMBER}`;
}
return build;
}
function distFileName(browserName, ext) {
return `dist-${browserName}${buildString()}.${ext}`;
}
function dist(browserName, manifest) {
return gulp
.src(paths.build + "**/*")
.pipe(filter(["**"].concat(filters.fonts).concat(filters.safari)))
.pipe(gulpif("popup/index.html", replace("__BROWSER__", "browser_" + browserName)))
.pipe(gulpif("manifest.json", jeditor(manifest)))
.pipe(zip(distFileName(browserName, "zip")))
.pipe(gulp.dest(paths.dist));
}
function distFirefox() {
return dist("firefox", (manifest) => {
delete manifest.storage;
return manifest;
});
}
function distOpera() {
return dist("opera", (manifest) => {
delete manifest.applications;
return manifest;
});
}
function distChrome() {
return dist("chrome", (manifest) => {
delete manifest.applications;
delete manifest.sidebar_action;
delete manifest.commands._execute_sidebar_action;
return manifest;
});
}
function distEdge() {
return dist("edge", (manifest) => {
delete manifest.applications;
delete manifest.sidebar_action;
delete manifest.commands._execute_sidebar_action;
return manifest;
});
}
function distSafariMas(cb) {
return distSafariApp(cb, "mas");
}
function distSafariMasDev(cb) {
return distSafariApp(cb, "masdev");
}
function distSafariDmg(cb) {
return distSafariApp(cb, "dmg");
}
function distSafariApp(cb, subBuildPath) {
const buildPath = paths.dist + "Safari/" + subBuildPath + "/";
const builtAppexPath = buildPath + "build/Release/safari.appex";
const builtAppexFrameworkPath = buildPath + "build/Release/safari.appex/Contents/Frameworks/";
const entitlementsPath = paths.safari + "safari/safari.entitlements";
var args = [
"--verbose",
"--force",
"-o",
"runtime",
"--sign",
"Developer ID Application: 8bit Solutions LLC",
"--entitlements",
entitlementsPath,
];
if (subBuildPath !== "dmg") {
args = [
"--verbose",
"--force",
"--sign",
subBuildPath === "mas"
? "3rd Party Mac Developer Application: Bitwarden Inc"
: "E661AB6249AEB60B0F47ABBD7326B2877D2575B0",
"--entitlements",
entitlementsPath,
];
}
return del([buildPath + "**/*"])
.then(() => safariCopyAssets(paths.safari + "**/*", buildPath))
.then(() => safariCopyBuild(paths.build + "**/*", buildPath + "safari/app"))
.then(() => {
const proc = child.spawn("xcodebuild", [
"-project",
buildPath + "desktop.xcodeproj",
"-alltargets",
"-configuration",
"Release",
]);
stdOutProc(proc);
return new Promise((resolve) => proc.on("close", resolve));
})
.then(() => {
const libs = fs
.readdirSync(builtAppexFrameworkPath)
.filter((p) => p.endsWith(".dylib"))
.map((p) => builtAppexFrameworkPath + p);
const libPromises = [];
libs.forEach((i) => {
const proc = child.spawn("codesign", args.concat([i]));
stdOutProc(proc);
libPromises.push(new Promise((resolve) => proc.on("close", resolve)));
});
return Promise.all(libPromises);
})
.then(() => {
const proc = child.spawn("codesign", args.concat([builtAppexPath]));
stdOutProc(proc);
return new Promise((resolve) => proc.on("close", resolve));
})
.then(
() => {
return cb;
},
() => {
return cb;
}
);
}
function safariCopyAssets(source, dest) {
return new Promise((resolve, reject) => {
gulp
.src(source)
.on("error", reject)
.pipe(gulpif("safari/Info.plist", replace("0.0.1", manifest.version)))
.pipe(
gulpif("safari/Info.plist", replace("0.0.2", process.env.BUILD_NUMBER || manifest.version))
)
.pipe(gulpif("desktop.xcodeproj/project.pbxproj", replace("../../../build", "../safari/app")))
.pipe(gulp.dest(dest))
.on("end", resolve);
});
}
function safariCopyBuild(source, dest) {
return new Promise((resolve, reject) => {
gulp
.src(source)
.on("error", reject)
.pipe(filter(["**"].concat(filters.fonts)))
.pipe(gulpif("popup/index.html", replace("__BROWSER__", "browser_safari")))
.pipe(
gulpif(
"manifest.json",
jeditor((manifest) => {
delete manifest.sidebar_action;
delete manifest.commands._execute_sidebar_action;
delete manifest.optional_permissions;
manifest.permissions.push("nativeMessaging");
return manifest;
})
)
)
.pipe(gulp.dest(dest))
.on("end", resolve);
});
}
function stdOutProc(proc) {
proc.stdout.on("data", (data) => console.log(data.toString()));
proc.stderr.on("data", (data) => console.error(data.toString()));
}
function ciCoverage(cb) {
return gulp
.src(paths.coverage + "**/*")
.pipe(filter(["**", "!coverage/coverage*.zip"]))
.pipe(zip(`coverage${buildString()}.zip`))
.pipe(gulp.dest(paths.coverage));
}
exports["dist:firefox"] = distFirefox;
exports["dist:chrome"] = distChrome;
exports["dist:opera"] = distOpera;
exports["dist:edge"] = distEdge;
exports["dist:safari"] = gulp.parallel(distSafariMas, distSafariMasDev, distSafariDmg);
exports["dist:safari:mas"] = distSafariMas;
exports["dist:safari:masdev"] = distSafariMasDev;
exports["dist:safari:dmg"] = distSafariDmg;
exports.dist = gulp.parallel(distFirefox, distChrome, distOpera, distEdge);
exports["ci:coverage"] = ciCoverage;
exports.ci = ciCoverage;

View File

@@ -9,7 +9,10 @@ module.exports = {
...sharedConfig,
preset: "jest-preset-angular",
setupFilesAfterEnv: ["<rootDir>/test.setup.ts"],
moduleNameMapper: pathsToModuleNameMapper(compilerOptions?.paths || {}, {
prefix: "<rootDir>/",
}),
moduleNameMapper: pathsToModuleNameMapper(
{ "@bitwarden/common/spec": ["../../libs/common/spec"], ...(compilerOptions?.paths ?? {}) },
{
prefix: "<rootDir>/",
},
),
};

View File

@@ -1,24 +1,34 @@
{
"name": "@bitwarden/browser",
"version": "2023.9.1",
"version": "2024.11.1",
"scripts": {
"build": "webpack",
"build:mv3": "cross-env MANIFEST_VERSION=3 webpack",
"build:watch": "webpack --watch",
"build:watch:mv3": "cross-env MANIFEST_VERSION=3 webpack --watch",
"build:prod": "cross-env NODE_ENV=production webpack",
"build:prod:watch": "cross-env NODE_ENV=production webpack --watch",
"dist": "npm run build:prod && gulp dist",
"dist:mv3": "cross-env MANIFEST_VERSION=3 npm run build:prod && cross-env MANIFEST_VERSION=3 gulp dist",
"dist:chrome": "npm run build:prod && gulp dist:chrome",
"dist:firefox": "npm run build:prod && gulp dist:firefox",
"dist:opera": "npm run build:prod && gulp dist:opera",
"dist:safari": "npm run build:prod && gulp dist:safari",
"dist:safari:mas": "npm run build:prod && gulp dist:safari:mas",
"dist:safari:masdev": "npm run build:prod && gulp dist:safari:masdev",
"dist:safari:dmg": "npm run build:prod && gulp dist:safari:dmg",
"build": "npm run build:chrome",
"build:chrome": "cross-env BROWSER=chrome MANIFEST_VERSION=3 webpack",
"build:edge": "cross-env BROWSER=edge webpack",
"build:firefox": "cross-env BROWSER=firefox webpack",
"build:opera": "cross-env BROWSER=opera webpack",
"build:safari": "cross-env BROWSER=safari webpack",
"build:watch": "npm run build:watch:chrome",
"build:watch:chrome": "npm run build:chrome -- --watch",
"build:watch:edge": "npm run build:edge -- --watch",
"build:watch:firefox": "npm run build:firefox -- --watch",
"build:watch:opera": "npm run build:opera -- --watch",
"build:watch:safari": "npm run build:safari -- --watch",
"build:prod:chrome": "cross-env NODE_ENV=production NODE_OPTIONS=\"--max-old-space-size=4096\" npm run build:chrome",
"build:prod:edge": "cross-env NODE_ENV=production NODE_OPTIONS=\"--max-old-space-size=4096\" npm run build:edge",
"build:prod:firefox": "cross-env NODE_ENV=production NODE_OPTIONS=\"--max-old-space-size=4096\" npm run build:firefox",
"build:prod:opera": "cross-env NODE_ENV=production NODE_OPTIONS=\"--max-old-space-size=4096\" npm run build:opera",
"build:prod:safari": "cross-env NODE_ENV=production NODE_OPTIONS=\"--max-old-space-size=4096\" npm run build:safari",
"dist:chrome": "npm run build:prod:chrome && mkdir -p dist && ./scripts/compress.ps1 dist-chrome.zip",
"dist:edge": "npm run build:prod:edge && mkdir -p dist && ./scripts/compress.ps1 dist-edge.zip",
"dist:firefox": "npm run build:prod:firefox && mkdir -p dist && ./scripts/compress.ps1 dist-firefox.zip",
"dist:opera": "npm run build:prod:opera && mkdir -p dist && ./scripts/compress.ps1 dist-opera.zip",
"dist:safari": "npm run build:prod:safari && ./scripts/package-safari.ps1",
"dist:edge:mv3": "cross-env MANIFEST_VERSION=3 npm run dist:edge",
"dist:firefox:mv3": "cross-env MANIFEST_VERSION=3 npm run dist:firefox",
"dist:opera:mv3": "cross-env MANIFEST_VERSION=3 npm run dist:opera",
"dist:safari:mv3": "cross-env MANIFEST_VERSION=3 npm run dist:safari",
"test": "jest",
"test:coverage": "jest --coverage --coverageDirectory=coverage",
"test:watch": "jest --watch",
"test:watch:all": "jest --watchAll"
}

View File

@@ -0,0 +1,30 @@
#!/usr/bin/env pwsh
####
# Compress the build directory into a zip file.
####
param (
[Parameter(Mandatory = $true)]
[String] $fileName
)
$buildDir = Join-Path $PSScriptRoot "../build"
$distDir = Join-Path $PSScriptRoot "../dist"
# Create dist directory if it doesn't exist
if (-not (Test-Path $distDir)) {
New-Item -ItemType Directory -Path $distDir
}
$distPath = Join-Path -Path $distDir -ChildPath $fileName
if (Test-Path $distPath) {
Remove-Item $distPath
}
# Compress build directory
if (Test-Path $buildDir) {
Compress-Archive -Path (Join-Path $buildDir "*") -DestinationPath $distPath
Write-Output "Zipped $buildDir into $distPath"
}

View File

@@ -0,0 +1,112 @@
#!/usr/bin/env pwsh
####
# Builds the safari appex.
####
$buildDir = Join-Path $PSScriptRoot "../build"
$distDir = Join-Path $PSScriptRoot "../dist"
Write-Output $PSScriptRoot
if (-not (Test-Path $buildDir)) {
Write-Output "No build directory found. Exiting..."
exit
}
# Create dist directory if it doesn't exist
if (-not (Test-Path $distDir)) {
New-Item -ItemType Directory -Path $distDir
}
$subBuildPaths = @("mas", "masdev", "dmg")
$safariSrc = Join-Path $PSScriptRoot "../src/safari"
$safariDistPath = Join-Path -Path $distDir -ChildPath "Safari"
if (-not (Test-Path $safariDistPath)) {
New-Item -ItemType Directory -Path $safariDistPath
}
# Delete old safari dists
Remove-Item -LiteralPath $safariDistPath -Force -Recurse
foreach ($subBuildPath in $subBuildPaths) {
$safariBuildPath = Join-Path -Path $safariDistPath -ChildPath $subBuildPath
$builtAppexPath = Join-Path -Path $safariBuildPath -ChildPath "build/Release/safari.appex"
$builtAppexFrameworkPath = Join-Path -Path $safariBuildPath -ChildPath "build/Release/safari.appex/Contents/Frameworks/"
$entitlementsPath = Join-Path -Path $safariSrc -ChildPath "safari/safari.entitlements"
switch ($subBuildPath) {
"mas" {
$codesignArgs = @(
"--verbose",
"--force",
"--sign",
'"3rd Party Mac Developer Application: Bitwarden Inc"',
"--entitlements",
$entitlementsPath
)
}
"masdev" {
$codesignArgs = @(
"--verbose",
"--force",
"--sign",
"E7C9978F6FBCE0553429185C405E61F5380BE8EB",
"--entitlements",
$entitlementsPath
)
}
"dmg" {
$codesignArgs = @(
"--verbose",
"--force",
"-o",
"runtime",
"--sign",
'"Developer ID Application: 8bit Solutions LLC"',
"--entitlements",
$entitlementsPath
)
}
}
# Copy safari src
Copy-Item -Path $safariSrc -Destination $safariBuildPath -Recurse
# Copy build
$target = Join-Path -Path $safariBuildPath -ChildPath "safari/app"
Copy-Item -Path $buildDir -Destination $target -Recurse
# Update versions
$jsonFilePath = Join-Path $buildDir "manifest.json"
$jsonContent = Get-Content -Path $jsonFilePath -Raw
$jsonObject = $jsonContent | ConvertFrom-Json
$infoFile = Join-Path -Path $safariBuildPath -ChildPath "safari/Info.plist"
(Get-Content $infoFile).Replace('0.0.1', $jsonObject.version).Replace('0.0.2', $jsonObject.version) | Set-Content $infoFile
$projectFile = Join-Path -Path $safariBuildPath -ChildPath "desktop.xcodeproj/project.pbxproj"
(Get-Content $projectFile).Replace('../../../build', "../safari/app") | Set-Content $projectFile
# Build using xcode
$xcodeBuildArgs = @(
"-project",
(Join-Path $safariBuildPath "desktop.xcodeproj"),
"-alltargets",
"-configuration",
"Release"
)
$proc = Start-Process "xcodebuild" -ArgumentList $xcodeBuildArgs -NoNewWindow -PassThru
$proc.WaitForExit()
# Codesign
$libs = Get-ChildItem -Path $builtAppexFrameworkPath -Filter "*.dylib"
foreach ($lib in $libs) {
$proc = Start-Process "codesign" -ArgumentList ($codesignArgs + $lib.FullName) -NoNewWindow -PassThru
$proc.WaitForExit()
}
$proc = Start-Process "codesign" -ArgumentList ($codesignArgs + $builtAppexPath) -NoNewWindow -PassThru
$proc.WaitForExit()
}

View File

@@ -0,0 +1,29 @@
import { mockDeep } from "jest-mock-extended";
/**
* Mocks a chrome.runtime.Port set up to send messages through `postMessage` to `onMessage.addListener` callbacks.
* @param name - The name of the port.
* @param immediateOnConnectExecution - Whether to immediately execute the onConnect callbacks against the new port.
* Defaults to false. If true, the creator of the port will not have had a chance to set up listeners yet.
* @returns a mock chrome.runtime.Port
*/
export function mockPorts() {
// notify listeners of a new port
(chrome.runtime.connect as jest.Mock).mockImplementation((portInfo) => {
const port = mockDeep<chrome.runtime.Port>();
port.name = portInfo.name;
// set message broadcast
(port.postMessage as jest.Mock).mockImplementation((message) => {
(port.onMessage.addListener as jest.Mock).mock.calls.forEach(([callbackFn]) => {
callbackFn(message, port);
});
});
(chrome.runtime.onConnect.addListener as jest.Mock).mock.calls.forEach(([callbackFn]) => {
callbackFn(port);
});
return port;
});
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More