mirror of
https://github.com/bitwarden/browser
synced 2026-02-06 11:43:51 +00:00
Merge branch 'main' into feature/i18n-component-template
This commit is contained in:
1
.browserslistrc
Normal file
1
.browserslistrc
Normal file
@@ -0,0 +1 @@
|
||||
> 0.5%, last 3 major versions, Firefox ESR, not dead
|
||||
@@ -7,5 +7,6 @@ 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/**"
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
**/build
|
||||
**/dist
|
||||
**/coverage
|
||||
.angular
|
||||
storybook-static
|
||||
|
||||
**/node_modules
|
||||
|
||||
**/webpack.*.js
|
||||
**/jest.config.js
|
||||
**/gulpfile.js
|
||||
|
||||
apps/browser/config/config.js
|
||||
apps/browser/src/auth/scripts/duo.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
|
||||
|
||||
tailwind.config.js
|
||||
libs/components/tailwind.config.base.js
|
||||
libs/components/tailwind.config.js
|
||||
|
||||
scripts/*.js
|
||||
242
.eslintrc.json
242
.eslintrc.json
@@ -1,242 +0,0 @@
|
||||
{
|
||||
"root": true,
|
||||
"env": {
|
||||
"browser": true,
|
||||
"webextensions": true
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.js"],
|
||||
"plugins": ["@typescript-eslint", "rxjs", "rxjs-angular", "import"],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"project": ["./tsconfig.eslint.json"],
|
||||
"sourceType": "module",
|
||||
"ecmaVersion": 2020
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:import/recommended",
|
||||
"plugin:import/typescript",
|
||||
"prettier",
|
||||
"plugin:rxjs/recommended",
|
||||
"plugin:storybook/recommended"
|
||||
],
|
||||
"settings": {
|
||||
"import/parsers": {
|
||||
"@typescript-eslint/parser": [".ts"]
|
||||
},
|
||||
"import/resolver": {
|
||||
"typescript": {
|
||||
"alwaysTryTypes": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"rules": {
|
||||
"@typescript-eslint/explicit-member-accessibility": [
|
||||
"error",
|
||||
{ "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": [
|
||||
"error",
|
||||
{
|
||||
"alphabetize": {
|
||||
"order": "asc"
|
||||
},
|
||||
"newlines-between": "always",
|
||||
"pathGroups": [
|
||||
{
|
||||
"pattern": "@bitwarden/**",
|
||||
"group": "external",
|
||||
"position": "after"
|
||||
},
|
||||
{
|
||||
"pattern": "src/**/*",
|
||||
"group": "parent",
|
||||
"position": "before"
|
||||
}
|
||||
],
|
||||
"pathGroupsExcludedImportTypes": ["builtin"]
|
||||
}
|
||||
],
|
||||
"rxjs-angular/prefer-takeuntil": "error",
|
||||
"rxjs/no-exposed-subjects": ["error", { "allowProtected": true }],
|
||||
"no-restricted-syntax": [
|
||||
"error",
|
||||
{
|
||||
"message": "Calling `svgIcon` directly is not allowed",
|
||||
"selector": "CallExpression[callee.name='svgIcon']"
|
||||
},
|
||||
{
|
||||
"message": "Accessing FormGroup using `get` is not allowed, use `.value` instead",
|
||||
"selector": "ChainExpression[expression.object.callee.property.name='get'][expression.property.name='value']"
|
||||
}
|
||||
],
|
||||
"curly": ["error", "all"],
|
||||
"import/namespace": ["off"], // This doesn't resolve namespace imports correctly, but TS will throw for this anyway
|
||||
"import/no-restricted-paths": [
|
||||
"error",
|
||||
{
|
||||
"zones": [
|
||||
{
|
||||
// avoid specific frameworks or large dependencies in common
|
||||
"target": "./libs/common/**/*",
|
||||
"from": [
|
||||
// Angular
|
||||
"./libs/angular/**/*",
|
||||
"./node_modules/@angular*/**/*",
|
||||
|
||||
// Node
|
||||
"./libs/node/**/*",
|
||||
|
||||
// Import/export
|
||||
"./libs/importer/**/*",
|
||||
"./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/**/*"] }]
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["*.html"],
|
||||
"parser": "@angular-eslint/template-parser",
|
||||
"plugins": ["@angular-eslint/template", "tailwindcss"],
|
||||
"rules": {
|
||||
"@angular-eslint/template/button-has-type": "error",
|
||||
"tailwindcss/no-custom-classname": [
|
||||
"error",
|
||||
{
|
||||
// uses negative lookahead to whitelist any class that doesn't start with "tw-"
|
||||
// in other words: classnames that start with tw- must be valid TailwindCSS classes
|
||||
"whitelist": ["(?!(tw)\\-).*"]
|
||||
}
|
||||
],
|
||||
"tailwindcss/enforces-negative-arbitrary-values": "error",
|
||||
"tailwindcss/enforces-shorthand": "error",
|
||||
"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": {
|
||||
"no-restricted-imports": ["error", { "patterns": ["@bitwarden/angular/*", "src/**/*"] }]
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["libs/auth/src/**/*.ts"],
|
||||
"rules": {
|
||||
"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": {
|
||||
"no-restricted-imports": ["error", { "patterns": ["@bitwarden/common/*", "src/**/*"] }]
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["libs/components/src/**/*.ts"],
|
||||
"rules": {
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{ "patterns": ["@bitwarden/components/*", "src/**/*", "@bitwarden/angular/*"] }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["libs/tools/export/vault-export/vault-export-core/src/**/*.ts"],
|
||||
"rules": {
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{ "patterns": ["@bitwarden/vault-export-core/*", "src/**/*"] }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["libs/importer/src/**/*.ts"],
|
||||
"rules": {
|
||||
"no-restricted-imports": ["error", { "patterns": ["@bitwarden/importer/*", "src/**/*"] }]
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["libs/node/src/**/*.ts"],
|
||||
"rules": {
|
||||
"no-restricted-imports": ["error", { "patterns": ["@bitwarden/node/*", "src/**/*"] }]
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["libs/platform/src/**/*.ts"],
|
||||
"rules": {
|
||||
"no-restricted-imports": ["error", { "patterns": ["@bitwarden/platform/*", "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']"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
143
.github/CODEOWNERS
vendored
143
.github/CODEOWNERS
vendored
@@ -4,8 +4,13 @@
|
||||
#
|
||||
# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
|
||||
|
||||
## Secrets Manager team files ##
|
||||
bitwarden_license/bit-web/src/app/secrets-manager @bitwarden/team-secrets-manager-dev
|
||||
## Desktop native module ##
|
||||
apps/desktop/desktop_native @bitwarden/team-platform-dev
|
||||
apps/desktop/desktop_native/objc/src/native/autofill @bitwarden/team-autofill-dev
|
||||
apps/desktop/desktop_native/core/src/autofill @bitwarden/team-autofill-dev
|
||||
## No ownership fo Cargo.lock and Cargo.toml to allow dependency updates
|
||||
apps/desktop/desktop_native/Cargo.lock
|
||||
apps/desktop/desktop_native/Cargo.toml
|
||||
|
||||
## Auth team files ##
|
||||
apps/browser/src/auth @bitwarden/team-auth-dev
|
||||
@@ -13,6 +18,7 @@ apps/cli/src/auth @bitwarden/team-auth-dev
|
||||
apps/desktop/src/auth @bitwarden/team-auth-dev
|
||||
apps/web/src/app/auth @bitwarden/team-auth-dev
|
||||
libs/auth @bitwarden/team-auth-dev
|
||||
libs/user-core @bitwarden/team-auth-dev
|
||||
# web connectors used for auth
|
||||
apps/web/src/connectors @bitwarden/team-auth-dev
|
||||
bitwarden_license/bit-web/src/app/auth @bitwarden/team-auth-dev
|
||||
@@ -30,12 +36,18 @@ libs/common/src/tools @bitwarden/team-tools-dev
|
||||
libs/importer @bitwarden/team-tools-dev
|
||||
libs/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
|
||||
## Dirt (Data Insights & Reporting) team files ##
|
||||
apps/web/src/app/dirt @bitwarden/team-data-insights-and-reporting-dev
|
||||
bitwarden_license/bit-common/src/dirt @bitwarden/team-data-insights-and-reporting-dev
|
||||
bitwarden_license/bit-web/src/app/dirt @bitwarden/team-data-insights-and-reporting-dev
|
||||
libs/dirt @bitwarden/team-data-insights-and-reporting-dev
|
||||
|
||||
## Localization/Crowdin (Platform and Tools team)
|
||||
apps/browser/src/_locales @bitwarden/team-tools-dev @bitwarden/team-platform-dev
|
||||
apps/browser/store/locales @bitwarden/team-tools-dev @bitwarden/team-platform-dev
|
||||
apps/cli/src/locales @bitwarden/team-tools-dev @bitwarden/team-platform-dev
|
||||
apps/desktop/src/locales @bitwarden/team-tools-dev @bitwarden/team-platform-dev
|
||||
apps/web/src/locales @bitwarden/team-tools-dev @bitwarden/team-platform-dev
|
||||
|
||||
## Vault team files ##
|
||||
apps/browser/src/vault @bitwarden/team-vault-dev
|
||||
@@ -52,55 +64,112 @@ 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/desktop/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/scripts @bitwarden/team-platform-dev
|
||||
apps/desktop/src/platform @bitwarden/team-platform-dev
|
||||
apps/desktop/resources @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
|
||||
libs/storage-core @bitwarden/team-platform-dev
|
||||
libs/logging @bitwarden/team-platform-dev
|
||||
libs/storage-test-utils @bitwarden/team-platform-dev
|
||||
libs/messaging @bitwarden/team-platform-dev
|
||||
libs/messaging-internal @bitwarden/team-platform-dev
|
||||
# Web utils used across app and connectors
|
||||
apps/web/src/utils/ @bitwarden/team-platform-dev
|
||||
# Web core and shared files
|
||||
apps/web/src/app/core @bitwarden/team-platform-dev
|
||||
apps/web/src/app/shared @bitwarden/team-platform-dev
|
||||
apps/web/src/translation-constants.ts @bitwarden/team-platform-dev
|
||||
# Workflows
|
||||
.github/workflows/automatic-issue-responses.yml @bitwarden/team-platform-dev
|
||||
.github/workflows/automatic-pull-request-responses.yml @bitwarden/team-platform-dev
|
||||
.github/workflows/build-browser-target.yml @bitwarden/team-platform-dev
|
||||
.github/workflows/build-browser.yml @bitwarden/team-platform-dev
|
||||
.github/workflows/build-cli-target.yml @bitwarden/team-platform-dev
|
||||
.github/workflows/build-cli.yml @bitwarden/team-platform-dev
|
||||
.github/workflows/build-desktop-target.yml @bitwarden/team-platform-dev
|
||||
.github/workflows/build-desktop.yml @bitwarden/team-platform-dev
|
||||
.github/workflows/build-web-target.yml @bitwarden/team-platform-dev
|
||||
.github/workflows/build-web.yml @bitwarden/team-platform-dev
|
||||
.github/workflows/chromatic.yml @bitwarden/team-platform-dev
|
||||
.github/workflows/crowdin-pull.yml @bitwarden/team-platform-dev
|
||||
.github/workflows/enforce-labels.yml @bitwarden/team-platform-dev
|
||||
.github/workflows/lint.yml @bitwarden/team-platform-dev
|
||||
.github/workflows/locales-lint.yml @bitwarden/team-platform-dev
|
||||
.github/workflows/repository-management.yml @bitwarden/team-platform-dev
|
||||
.github/workflows/scan.yml @bitwarden/team-platform-dev
|
||||
.github/workflows/stale-bot.yml @bitwarden/team-platform-dev
|
||||
.github/workflows/test.yml @bitwarden/team-platform-dev
|
||||
.github/workflows/version-auto-bump.yml @bitwarden/team-platform-dev
|
||||
# ESLint custom rules
|
||||
libs/eslint @bitwarden/team-platform-dev
|
||||
# Typescript tooling
|
||||
tsconfig.base.json @bitwarden/team-platform-dev
|
||||
nx.json @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
|
||||
apps/desktop/src/app/components/fido2placeholder.component.ts @bitwarden/team-autofill-dev
|
||||
apps/desktop/desktop_native/windows_plugin_authenticator @bitwarden/team-autofill-dev
|
||||
apps/desktop/desktop_native/autotype @bitwarden/team-autofill-dev
|
||||
# DuckDuckGo integration
|
||||
apps/desktop/native-messaging-test-runner @bitwarden/team-autofill-dev
|
||||
apps/desktop/src/services/duckduckgo-message-handler.service.ts @bitwarden/team-autofill-dev
|
||||
apps/desktop/src/services/encrypted-message-handler.service.ts @bitwarden/team-autofill-dev
|
||||
.github/workflows/alert-ddg-files-modified.yml @bitwarden/team-autofill-dev
|
||||
# SSH Agent
|
||||
apps/desktop/desktop_native/core/src/ssh_agent @bitwarden/team-autofill-dev @bitwarden/wg-ssh-keys
|
||||
|
||||
## Component Library ##
|
||||
.storybook @bitwarden/team-component-library
|
||||
libs/components @bitwarden/team-component-library
|
||||
apps/web/src/app/layouts/header
|
||||
## UI Foundation ##
|
||||
.storybook @bitwarden/team-ui-foundation
|
||||
libs/components @bitwarden/team-ui-foundation
|
||||
libs/ui @bitwarden/team-ui-foundation
|
||||
apps/browser/src/platform/popup/layout @bitwarden/team-ui-foundation
|
||||
apps/browser/src/popup/app-routing.animations.ts @bitwarden/team-ui-foundation
|
||||
apps/browser/src/popup/components/extension-anon-layout-wrapper @bitwarden/team-ui-foundation
|
||||
apps/web/src/app/layouts @bitwarden/team-ui-foundation
|
||||
|
||||
## Desktop native module ##
|
||||
apps/desktop/desktop_native @bitwarden/team-platform-dev
|
||||
|
||||
## DevOps team files ##
|
||||
/.github/workflows @bitwarden/dept-devops
|
||||
## 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
|
||||
libs/key-management-ui @bitwarden/team-key-management-dev
|
||||
libs/common/src/key-management @bitwarden/team-key-management-dev
|
||||
# Node-cryptofunction service
|
||||
libs/node @bitwarden/team-key-management-dev
|
||||
|
||||
# DevOps for Docker changes.
|
||||
**/Dockerfile @bitwarden/dept-devops
|
||||
**/*.Dockerfile @bitwarden/dept-devops
|
||||
**/.dockerignore @bitwarden/dept-devops
|
||||
**/entrypoint.sh @bitwarden/dept-devops
|
||||
apps/desktop/desktop_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
|
||||
apps/desktop/src/services/biometric-message-handler.service.ts @bitwarden/team-key-management-dev
|
||||
|
||||
## Locales ##
|
||||
apps/browser/src/_locales/en/messages.json
|
||||
@@ -108,3 +177,31 @@ 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
|
||||
|
||||
## 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
|
||||
.github/workflows/release-browser.yml @bitwarden/dept-bre
|
||||
.github/workflows/release-cli.yml @bitwarden/dept-bre
|
||||
.github/workflows/release-desktop-beta.yml @bitwarden/dept-bre
|
||||
.github/workflows/release-desktop.yml @bitwarden/dept-bre
|
||||
.github/workflows/release-web.yml @bitwarden/dept-bre
|
||||
|
||||
## Docker files have shared ownership ##
|
||||
**/Dockerfile
|
||||
**/*.Dockerfile
|
||||
**/.dockerignore
|
||||
**/entrypoint.sh
|
||||
|
||||
## Overrides
|
||||
# For the time being platform owns tsconfig and jest config
|
||||
# These overrides will be removed after Nx is implemented
|
||||
# To track that effort please see https://bitwarden.atlassian.net/browse/PM-21636
|
||||
**/tsconfig.json @bitwarden/team-platform-dev
|
||||
**/jest.config.js @bitwarden/team-platform-dev
|
||||
**/project.jsons @bitwarden/team-platform-dev
|
||||
|
||||
13
.github/DISCUSSION_TEMPLATE/password-manager.yml
vendored
13
.github/DISCUSSION_TEMPLATE/password-manager.yml
vendored
@@ -1,8 +1,19 @@
|
||||
labels: ["discussions-new"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
If you would like to contribute code to the Bitwarden codebase for consideration, please review [https://contributing.bitwarden.com/](https://contributing.bitwarden.com/) before posting. To keep discussion on topic, posts that do not include a proposal for a code contribution you wish to develop will be removed. For feature requests and community discussion, please visit https://community.bitwarden.com/
|
||||
If you would like to contribute code to the Bitwarden codebase for consideration, please review [https://contributing.bitwarden.com/](https://contributing.bitwarden.com/) before posting. To keep discussion on topic, posts that do not include a proposal for a code contribution you wish to develop will be removed.
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Select Topic Area
|
||||
description: "What would you like to discuss? :warning: For feature requests and product feedback, please visit https://community.bitwarden.com/"
|
||||
options:
|
||||
- "✅ Code Contribution Proposal"
|
||||
- "🚫 Product Feedback"
|
||||
- "🚫 Feature Request"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Code Contribution Proposal
|
||||
|
||||
13
.github/DISCUSSION_TEMPLATE/secrets-manager.yml
vendored
13
.github/DISCUSSION_TEMPLATE/secrets-manager.yml
vendored
@@ -1,8 +1,19 @@
|
||||
labels: ["discussions-new"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
If you would like to contribute code to the Bitwarden codebase for consideration, please review [https://contributing.bitwarden.com/](https://contributing.bitwarden.com/) before posting. To keep discussion on topic, posts that do not include a proposal for a code contribution you wish to develop will be removed. For feature requests and community discussion, please visit https://community.bitwarden.com/
|
||||
If you would like to contribute code to the Bitwarden codebase for consideration, please review [https://contributing.bitwarden.com/](https://contributing.bitwarden.com/) before posting. To keep discussion on topic, posts that do not include a proposal for a code contribution you wish to develop will be removed.
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Select Topic Area
|
||||
description: "What would you like to discuss? :warning: For feature requests and product feedback, please visit https://community.bitwarden.com/"
|
||||
options:
|
||||
- "✅ Code Contribution Proposal"
|
||||
- "🚫 Product Feedback"
|
||||
- "🚫 Feature Request"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Code Contribution Proposal
|
||||
|
||||
8
.github/ISSUE_TEMPLATE/browser.yml
vendored
8
.github/ISSUE_TEMPLATE/browser.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Browser Bug Report
|
||||
name: Browser Extension Bug Report
|
||||
description: File a bug report
|
||||
labels: [bug, browser]
|
||||
body:
|
||||
@@ -84,11 +84,11 @@ body:
|
||||
attributes:
|
||||
label: Browser Version
|
||||
description: What version of the browser(s) are you seeing the problem on?
|
||||
- type: input
|
||||
- type: textarea
|
||||
id: version
|
||||
attributes:
|
||||
label: Build Version
|
||||
description: What version of our software are you running? (go to "Settings" → "About" in the extension)
|
||||
label: Environment Versions
|
||||
description: Copy from "Settings" → "About" → "About Bitwarden" in the extension. Should include the extension version and server environment.
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
|
||||
1
.github/ISSUE_TEMPLATE/desktop.yml
vendored
1
.github/ISSUE_TEMPLATE/desktop.yml
vendored
@@ -73,6 +73,7 @@ body:
|
||||
- Homebrew
|
||||
- Chocolatey
|
||||
- Snap
|
||||
- Flatpak
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
|
||||
3
.github/ISSUE_TEMPLATE/web.yml
vendored
3
.github/ISSUE_TEMPLATE/web.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Web Bug Report
|
||||
name: Web App Bug Report
|
||||
description: File a bug report
|
||||
labels: [bug, web]
|
||||
body:
|
||||
@@ -77,6 +77,7 @@ body:
|
||||
- Opera
|
||||
- Brave
|
||||
- Vivaldi
|
||||
- DuckDuckGo
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
|
||||
48
.github/PULL_REQUEST_TEMPLATE.md
vendored
48
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -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
|
||||
|
||||
67
.github/codecov.yml
vendored
67
.github/codecov.yml
vendored
@@ -1,2 +1,69 @@
|
||||
ignore:
|
||||
- "**/*.spec.ts" # Tests
|
||||
|
||||
component_management:
|
||||
default_rules:
|
||||
statuses:
|
||||
- type: project
|
||||
target: auto
|
||||
individual_components:
|
||||
- component_id: key-management-biometrics
|
||||
name: Key Management - Biometrics
|
||||
paths:
|
||||
- apps/browser/src/key-management/biometrics/**
|
||||
- apps/cli/src/key-management/cli-biometrics-service.ts
|
||||
- apps/desktop/desktop_native/core/src/biometric/**
|
||||
- apps/desktop/src/key-management/biometrics/**
|
||||
- apps/desktop/src/services/biometric-message-handler.service.ts
|
||||
- apps/web/src/app/key-management/web-biometric.service.ts
|
||||
- libs/key-management/src/biometrics/**
|
||||
- component_id: key-management-lock
|
||||
name: Key Management - Lock
|
||||
paths:
|
||||
- apps/browser/src/key-management/lock/**
|
||||
- apps/desktop/src/key-management/lock/**
|
||||
- apps/web/src/app/key-management/lock/**
|
||||
- libs/key-management-ui/src/lock/**
|
||||
- libs/common/src/key-management/device-trust/**
|
||||
- component_id: key-management-ipc
|
||||
name: Key Management - IPC
|
||||
paths:
|
||||
- apps/browser/src/background/nativeMessaging.background.ts
|
||||
- apps/desktop/src/services/native-messaging.service.ts
|
||||
- component_id: key-management-key-rotation
|
||||
name: Key Management - Key Rotation
|
||||
paths:
|
||||
- apps/web/src/app/key-management/key-rotation/**
|
||||
- apps/web/src/app/key-management/migrate-encryption/**
|
||||
- libs/key-management/src/user-asymmetric-key-regeneration/**
|
||||
- component_id: key-management-process-reload
|
||||
name: Key Management - Process Reload
|
||||
paths:
|
||||
- apps/web/src/app/key-management/services/web-process-reload.service.ts
|
||||
- libs/common/src/key-management/services/default-process-reload.service.ts
|
||||
- component_id: key-management-keys
|
||||
name: Key Management - Keys
|
||||
paths:
|
||||
- apps/desktop/src/key-management/electron-key.service.ts
|
||||
- libs/key-management/src/kdf-config.service.ts
|
||||
- libs/key-management/src/key.service.ts
|
||||
- libs/common/src/key-management/master-password/**
|
||||
- libs/common/src/key-management/key-connector/**
|
||||
- component_id: key-management-crypto
|
||||
name: Key Management - Crypto
|
||||
paths:
|
||||
- libs/common/src/key-management/crypto/**
|
||||
- component_id: key-management
|
||||
name: Key Management
|
||||
paths:
|
||||
- apps/browser/src/key-management/**
|
||||
- apps/browser/src/background/nativeMessaging.background.ts
|
||||
- apps/cli/src/key-management/**
|
||||
- apps/desktop/desktop_native/core/src/biometric/**
|
||||
- apps/desktop/src/key-management/**
|
||||
- apps/desktop/src/services/biometric-message-handler.service.ts
|
||||
- apps/desktop/src/services/native-messaging.service.ts
|
||||
- apps/web/src/app/key-management/**
|
||||
- libs/common/src/key-management/**
|
||||
- libs/key-management/**
|
||||
- libs/key-management-ui/**
|
||||
|
||||
263
.github/renovate.json
vendored
263
.github/renovate.json
vendored
@@ -1,263 +0,0 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": ["github>bitwarden/renovate-config"],
|
||||
"enabledManagers": ["cargo", "github-actions", "npm"],
|
||||
"packageRules": [
|
||||
{
|
||||
"groupName": "gh minor",
|
||||
"matchManagers": ["github-actions"],
|
||||
"matchUpdateTypes": ["minor", "patch"]
|
||||
},
|
||||
{
|
||||
"matchManagers": ["github-actions"],
|
||||
"commitMessagePrefix": "[deps] DevOps:"
|
||||
},
|
||||
{
|
||||
"matchManagers": ["cargo"],
|
||||
"commitMessagePrefix": "[deps] Platform:"
|
||||
},
|
||||
{
|
||||
"matchPackageNames": ["typescript", "zone.js"],
|
||||
"matchUpdateTypes": ["major", "minor"],
|
||||
"description": "Determined by Angular",
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"matchPackageNames": ["typescript", "zone.js"],
|
||||
"matchUpdateTypes": "patch"
|
||||
},
|
||||
{
|
||||
"groupName": "jest",
|
||||
"matchPackageNames": ["@types/jest", "jest", "ts-jest", "jest-preset-angular"],
|
||||
"matchUpdateTypes": "major"
|
||||
},
|
||||
{
|
||||
"matchPackageNames": [
|
||||
"@ngtools/webpack",
|
||||
"base64-loader",
|
||||
"buffer",
|
||||
"bufferutil",
|
||||
"clean-webpack-plugin",
|
||||
"copy-webpack-plugin",
|
||||
"core-js",
|
||||
"css-loader",
|
||||
"html-loader",
|
||||
"html-webpack-injector",
|
||||
"html-webpack-plugin",
|
||||
"mini-css-extract-plugin",
|
||||
"ngx-infinite-scroll",
|
||||
"postcss",
|
||||
"postcss-loader",
|
||||
"process",
|
||||
"sass",
|
||||
"sass-loader",
|
||||
"style-loader",
|
||||
"ts-loader",
|
||||
"tsconfig-paths-webpack-plugin",
|
||||
"url",
|
||||
"util",
|
||||
"webpack",
|
||||
"webpack-cli",
|
||||
"webpack-dev-server",
|
||||
"webpack-node-externals"
|
||||
],
|
||||
"description": "Admin Console owned dependencies",
|
||||
"commitMessagePrefix": "[deps] AC:",
|
||||
"reviewers": ["team:team-admin-console-dev"]
|
||||
},
|
||||
{
|
||||
"matchPackageNames": [
|
||||
"@types/duo_web_sdk",
|
||||
"@types/node-ipc",
|
||||
"duo_web_sdk",
|
||||
"node-ipc",
|
||||
"qrious",
|
||||
"regedit"
|
||||
],
|
||||
"description": "Auth owned dependencies",
|
||||
"commitMessagePrefix": "[deps] Auth:",
|
||||
"reviewers": ["team:team-auth-dev"]
|
||||
},
|
||||
{
|
||||
"matchPackageNames": [
|
||||
"@webcomponents/custom-elements",
|
||||
"concurrently",
|
||||
"cross-env",
|
||||
"del",
|
||||
"gulp",
|
||||
"gulp-filter",
|
||||
"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": [
|
||||
"@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",
|
||||
"@types/argon2-browser",
|
||||
"@types/chrome",
|
||||
"@types/firefox-webext-browser",
|
||||
"@types/jquery",
|
||||
"@types/node",
|
||||
"@types/node-forge",
|
||||
"argon2",
|
||||
"argon2-browser",
|
||||
"big-integer",
|
||||
"bootstrap",
|
||||
"jquery",
|
||||
"node-forge",
|
||||
"popper.js",
|
||||
"rxjs",
|
||||
"type-fest",
|
||||
"typescript",
|
||||
"zone.js"
|
||||
],
|
||||
"description": "Platform owned dependencies",
|
||||
"commitMessagePrefix": "[deps] Platform:",
|
||||
"reviewers": ["team:team-platform-dev"]
|
||||
},
|
||||
{
|
||||
"matchPackageNames": [
|
||||
"@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",
|
||||
"chromatic",
|
||||
"ngx-toastr",
|
||||
"react",
|
||||
"react-dom",
|
||||
"remark-gfm",
|
||||
"storybook",
|
||||
"tailwindcss"
|
||||
],
|
||||
"description": "Component library owned dependencies",
|
||||
"commitMessagePrefix": "[deps] Platform (CL):",
|
||||
"reviewers": ["team:team-component-library"]
|
||||
},
|
||||
{
|
||||
"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": [
|
||||
"@electron/notarize",
|
||||
"@electron/rebuild",
|
||||
"@microsoft/signalr-protocol-msgpack",
|
||||
"@microsoft/signalr",
|
||||
"@types/jsdom",
|
||||
"@types/papaparse",
|
||||
"@types/zxcvbn",
|
||||
"electron-builder",
|
||||
"electron-log",
|
||||
"electron-reload",
|
||||
"electron-store",
|
||||
"electron-updater",
|
||||
"electron",
|
||||
"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/lowdb",
|
||||
"@types/lunr",
|
||||
"@types/node-fetch",
|
||||
"@types/proper-lockfile",
|
||||
"@types/retry",
|
||||
"chalk",
|
||||
"commander",
|
||||
"form-data",
|
||||
"https-proxy-agent",
|
||||
"inquirer",
|
||||
"koa",
|
||||
"koa-bodyparser",
|
||||
"koa-json",
|
||||
"lowdb",
|
||||
"lunr",
|
||||
"multer",
|
||||
"node-fetch",
|
||||
"open",
|
||||
"pkg",
|
||||
"proper-lockfile",
|
||||
"qrcode-parser"
|
||||
],
|
||||
"description": "Vault owned dependencies",
|
||||
"commitMessagePrefix": "[deps] Vault:",
|
||||
"reviewers": ["team:team-vault-dev"]
|
||||
}
|
||||
],
|
||||
"ignoreDeps": ["@types/koa-bodyparser", "bootstrap", "node-ipc", "node", "npm", "regedit"]
|
||||
}
|
||||
420
.github/renovate.json5
vendored
Normal file
420
.github/renovate.json5
vendored
Normal file
@@ -0,0 +1,420 @@
|
||||
{
|
||||
$schema: "https://docs.renovatebot.com/renovate-schema.json",
|
||||
extends: ["github>bitwarden/renovate-config"], // Extends our default configuration for pinned dependencies
|
||||
enabledManagers: ["cargo", "github-actions", "npm"],
|
||||
packageRules: [
|
||||
{
|
||||
// Group all Github Action minor updates together to reduce PR noise.
|
||||
groupName: "Minor github-actions updates",
|
||||
matchManagers: ["github-actions"],
|
||||
matchUpdateTypes: ["minor"],
|
||||
addLabels: ["hold"],
|
||||
},
|
||||
{
|
||||
// Enable support for Rust toolchain updates.
|
||||
matchManagers: ["custom.regex"],
|
||||
matchDepNames: ["rust"],
|
||||
commitMessageTopic: "Rust",
|
||||
},
|
||||
{
|
||||
// By default, we send patch updates to the Dependency Dashboard and do not generate a PR.
|
||||
// We want to generate PRs for a select number of dependencies to ensure we stay up to date on these.
|
||||
matchPackageNames: ["browserslist", "electron", "rxjs", "typescript", "webpack", "zone.js"],
|
||||
matchUpdateTypes: ["patch"],
|
||||
dependencyDashboardApproval: false,
|
||||
},
|
||||
{
|
||||
// Disable major and minor updates for TypeScript and Zone.js because they are managed by Angular.
|
||||
matchPackageNames: ["typescript", "zone.js"],
|
||||
matchUpdateTypes: ["major", "minor"],
|
||||
description: "Determined by Angular",
|
||||
enabled: false,
|
||||
},
|
||||
{
|
||||
// Disable major updates for core Angular dependencies because they are managed through ng update
|
||||
// when we decide to upgrade.
|
||||
matchSourceUrls: [
|
||||
"https://github.com/angular-eslint/angular-eslint",
|
||||
"https://github.com/angular/angular-cli",
|
||||
"https://github.com/angular/angular",
|
||||
"https://github.com/angular/components",
|
||||
"https://github.com/ng-select/ng-select",
|
||||
],
|
||||
matchUpdateTypes: ["major"],
|
||||
description: "Manually updated using ng update",
|
||||
enabled: false,
|
||||
},
|
||||
{
|
||||
matchPackageNames: ["buffer", "bufferutil", "core-js", "process", "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: [
|
||||
"@angular-eslint/schematics",
|
||||
"@eslint/compat",
|
||||
"@typescript-eslint/rule-tester",
|
||||
"@typescript-eslint/utils",
|
||||
"angular-eslint",
|
||||
"eslint-config-prettier",
|
||||
"eslint-import-resolver-typescript",
|
||||
"eslint-plugin-import",
|
||||
"eslint-plugin-rxjs-angular",
|
||||
"eslint-plugin-rxjs",
|
||||
"eslint-plugin-storybook",
|
||||
"eslint-plugin-tailwindcss",
|
||||
"eslint",
|
||||
"husky",
|
||||
"lint-staged",
|
||||
"typescript-eslint",
|
||||
],
|
||||
description: "Architecture owned dependencies",
|
||||
commitMessagePrefix: "[deps] Architecture:",
|
||||
reviewers: ["team:dept-architecture"],
|
||||
},
|
||||
{
|
||||
matchPackageNames: [
|
||||
"@angular-eslint/schematics",
|
||||
"@eslint/compat",
|
||||
"@typescript-eslint/rule-tester",
|
||||
"@typescript-eslint/utils",
|
||||
"angular-eslint",
|
||||
"eslint-config-prettier",
|
||||
"eslint-import-resolver-typescript",
|
||||
"eslint-plugin-import",
|
||||
"eslint-plugin-rxjs-angular",
|
||||
"eslint-plugin-rxjs",
|
||||
"eslint-plugin-storybook",
|
||||
"eslint-plugin-tailwindcss",
|
||||
"eslint",
|
||||
"husky",
|
||||
"lint-staged",
|
||||
"typescript-eslint",
|
||||
],
|
||||
groupName: "Minor and patch linting updates",
|
||||
matchUpdateTypes: ["minor", "patch"],
|
||||
},
|
||||
{
|
||||
matchPackageNames: [
|
||||
"@emotion/css",
|
||||
"@webcomponents/custom-elements",
|
||||
"bitwarden-russh",
|
||||
"bytes",
|
||||
"concurrently",
|
||||
"cross-env",
|
||||
"del",
|
||||
"ed25519",
|
||||
"lit",
|
||||
"@lit-labs/signals",
|
||||
"patch-package",
|
||||
"pkcs8",
|
||||
"prettier",
|
||||
"prettier-plugin-tailwindcss",
|
||||
"rimraf",
|
||||
"ssh-encoding",
|
||||
"ssh-key",
|
||||
"@storybook/web-components-webpack5",
|
||||
"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",
|
||||
"@bitwarden/sdk-internal",
|
||||
"@electron/fuses",
|
||||
"@electron/notarize",
|
||||
"@electron/rebuild",
|
||||
"@ngtools/webpack",
|
||||
"@nx/devkit",
|
||||
"@nx/eslint",
|
||||
"@nx/jest",
|
||||
"@nx/js",
|
||||
"@types/chrome",
|
||||
"@types/firefox-webext-browser",
|
||||
"@types/glob",
|
||||
"@types/lowdb",
|
||||
"@types/node",
|
||||
"@types/node-forge",
|
||||
"@types/node-ipc",
|
||||
"@yao-pkg/pkg",
|
||||
"anyhow",
|
||||
"arboard",
|
||||
"babel-loader",
|
||||
"base64-loader",
|
||||
"base64",
|
||||
"bindgen",
|
||||
"browserslist",
|
||||
"byteorder",
|
||||
"bytes",
|
||||
"core-foundation",
|
||||
"copy-webpack-plugin",
|
||||
"css-loader",
|
||||
"dirs",
|
||||
"electron",
|
||||
"electron-builder",
|
||||
"electron-log",
|
||||
"electron-reload",
|
||||
"electron-store",
|
||||
"electron-updater",
|
||||
"embed_plist",
|
||||
"futures",
|
||||
"hex",
|
||||
"homedir",
|
||||
"html-loader",
|
||||
"html-webpack-injector",
|
||||
"html-webpack-plugin",
|
||||
"interprocess",
|
||||
"json5",
|
||||
"keytar",
|
||||
"libc",
|
||||
"log",
|
||||
"lowdb",
|
||||
"mini-css-extract-plugin",
|
||||
"napi",
|
||||
"napi-build",
|
||||
"napi-derive",
|
||||
"node-forge",
|
||||
"node-ipc",
|
||||
"nx",
|
||||
"oo7",
|
||||
"oslog",
|
||||
"pin-project",
|
||||
"pkg",
|
||||
"postcss",
|
||||
"postcss-loader",
|
||||
"rand",
|
||||
"rxjs",
|
||||
"sass",
|
||||
"sass-loader",
|
||||
"scopeguard",
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"simplelog",
|
||||
"style-loader",
|
||||
"sysinfo",
|
||||
"ts-node",
|
||||
"ts-loader",
|
||||
"tsconfig-paths-webpack-plugin",
|
||||
"type-fest",
|
||||
"typenum",
|
||||
"typescript",
|
||||
"typescript-strict-plugin",
|
||||
"uniffi",
|
||||
"webpack",
|
||||
"webpack-cli",
|
||||
"webpack-dev-server",
|
||||
"webpack-node-externals",
|
||||
"widestring",
|
||||
"windows",
|
||||
"windows-future",
|
||||
"windows-registry",
|
||||
"zbus",
|
||||
"zbus_polkit",
|
||||
],
|
||||
description: "Platform owned dependencies",
|
||||
commitMessagePrefix: "[deps] Platform:",
|
||||
reviewers: ["team:team-platform-dev"],
|
||||
},
|
||||
{
|
||||
// We need to group all napi-related packages together to avoid build errors caused by version incompatibilities.
|
||||
groupName: "napi",
|
||||
matchPackageNames: ["napi", "napi-build", "napi-derive"],
|
||||
},
|
||||
{
|
||||
// We need to group all macOS/iOS binding-related packages together to avoid build errors caused by version incompatibilities.
|
||||
groupName: "macOS/iOS bindings",
|
||||
matchPackageNames: ["core-foundation", "security-framework", "security-framework-sys"],
|
||||
},
|
||||
{
|
||||
// We need to group all zbus-related packages together to avoid build errors caused by version incompatibilities.
|
||||
groupName: "zbus",
|
||||
matchPackageNames: ["zbus", "zbus_polkit"],
|
||||
},
|
||||
{
|
||||
// We group all webpack build-related minor and patch updates together to reduce PR noise.
|
||||
// We include patch updates here because we want PRs for webpack patch updates and it's in this group.
|
||||
matchPackageNames: [
|
||||
"@babel/core",
|
||||
"@babel/preset-env",
|
||||
"babel-loader",
|
||||
"base64-loader",
|
||||
"browserslist",
|
||||
"copy-webpack-plugin",
|
||||
"css-loader",
|
||||
"html-loader",
|
||||
"html-webpack-injector",
|
||||
"html-webpack-plugin",
|
||||
"mini-css-extract-plugin",
|
||||
"postcss-loader",
|
||||
"postcss",
|
||||
"sass-loader",
|
||||
"sass",
|
||||
"style-loader",
|
||||
"ts-loader",
|
||||
"tsconfig-paths-webpack-plugin",
|
||||
"webpack-cli",
|
||||
"webpack-dev-server",
|
||||
"webpack-node-externals",
|
||||
"webpack",
|
||||
],
|
||||
description: "webpack-related build dependencies",
|
||||
groupName: "Minor and patch webpack updates",
|
||||
matchUpdateTypes: ["minor", "patch"],
|
||||
},
|
||||
{
|
||||
matchPackageNames: [
|
||||
"@angular-devkit/build-angular",
|
||||
"@angular/animations",
|
||||
"@angular/cdk",
|
||||
"@angular/cli",
|
||||
"@angular/common",
|
||||
"@angular/compiler-cli",
|
||||
"@angular/compiler",
|
||||
"@angular/core",
|
||||
"@angular/forms",
|
||||
"@angular/platform-browser-dynamic",
|
||||
"@angular/platform-browser",
|
||||
"@angular/platform",
|
||||
"@angular/router",
|
||||
"axe-playwright",
|
||||
"@compodoc/compodoc",
|
||||
"@ng-select/ng-select",
|
||||
"@storybook/addon-a11y",
|
||||
"@storybook/addon-actions",
|
||||
"@storybook/addon-designs",
|
||||
"@storybook/addon-essentials",
|
||||
"@storybook/addon-interactions",
|
||||
"@storybook/addon-links",
|
||||
"@storybook/test-runner",
|
||||
"@storybook/addon-themes",
|
||||
"@storybook/angular",
|
||||
"@storybook/manager-api",
|
||||
"@storybook/theming",
|
||||
"@types/react",
|
||||
"autoprefixer",
|
||||
"bootstrap",
|
||||
"chromatic",
|
||||
"ngx-toastr",
|
||||
"react",
|
||||
"react-dom",
|
||||
"remark-gfm",
|
||||
"storybook",
|
||||
"tailwindcss",
|
||||
"zone.js",
|
||||
],
|
||||
description: "UI Foundation owned dependencies",
|
||||
commitMessagePrefix: "[deps] UI Foundation:",
|
||||
reviewers: ["team:team-ui-foundation"],
|
||||
},
|
||||
{
|
||||
matchPackageNames: [
|
||||
"@types/jest",
|
||||
"jest-junit",
|
||||
"jest-mock-extended",
|
||||
"jest-preset-angular",
|
||||
"jest-diff",
|
||||
"ts-jest",
|
||||
],
|
||||
description: "Secrets Manager owned dependencies",
|
||||
commitMessagePrefix: "[deps] SM:",
|
||||
reviewers: ["team:team-secrets-manager-dev"],
|
||||
},
|
||||
{
|
||||
// We need to update several Jest-related packages together, for version compatibility.
|
||||
groupName: "jest",
|
||||
matchPackageNames: ["@types/jest", "jest", "ts-jest", "jest-preset-angular"],
|
||||
},
|
||||
{
|
||||
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: ["aes", "big-integer", "cbc", "rsa", "russh-cryptovec", "sha2"],
|
||||
description: "Key Management owned dependencies",
|
||||
commitMessagePrefix: "[deps] KM:",
|
||||
reviewers: ["team:team-key-management-dev"],
|
||||
},
|
||||
{
|
||||
// Any versions of lowdb above 1.0.0 are not compatible with CommonJS.
|
||||
matchPackageNames: ["lowdb"],
|
||||
allowedVersions: "1.0.0",
|
||||
description: "Higher versions of lowdb are not compatible with CommonJS",
|
||||
},
|
||||
{
|
||||
// Pin types as well since we are not upgrading past v1 (and also v2+ does not need separate types).
|
||||
matchPackageNames: ["@types/lowdb"],
|
||||
allowedVersions: "< 2.0.0",
|
||||
description: "Higher versions of lowdb do not need separate types",
|
||||
},
|
||||
],
|
||||
ignoreDeps: ["@types/koa-bodyparser", "bootstrap", "node-ipc", "@bitwarden/sdk-internal"],
|
||||
}
|
||||
27
.github/whitelist-capital-letters.txt
vendored
27
.github/whitelist-capital-letters.txt
vendored
@@ -3,32 +3,12 @@
|
||||
./apps/browser/src/safari/desktop/Assets.xcassets/AppIcon.appiconset
|
||||
./apps/browser/src/safari/desktop/Base.lproj
|
||||
./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/admin-console/README.md
|
||||
./libs/auth/README.md
|
||||
./libs/billing/README.md
|
||||
./libs/platform/README.md
|
||||
./libs/tools/README.md
|
||||
./libs/tools/export/vault-export/README.md
|
||||
./libs/vault/README.md
|
||||
./README.md
|
||||
./LICENSE_BITWARDEN.txt
|
||||
./CONTRIBUTING.md
|
||||
./LICENSE_GPL.txt
|
||||
./LICENSE.txt
|
||||
./apps/web/Dockerfile
|
||||
./apps/web/README.md
|
||||
./apps/desktop/resources/installerSidebar.bmp
|
||||
./apps/desktop/resources/appx/SplashScreen.png
|
||||
./apps/desktop/resources/appx/BadgeLogo.png
|
||||
@@ -36,16 +16,10 @@
|
||||
./apps/desktop/resources/appx/StoreLogo.png
|
||||
./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/models/browserComponentState.ts
|
||||
./apps/browser/src/models/browserSendComponentState.ts
|
||||
./apps/browser/src/models/browserGroupingsComponentState.ts
|
||||
./apps/browser/src/models/biometricErrors.ts
|
||||
./apps/browser/src/browser/safariApp.ts
|
||||
@@ -60,3 +34,4 @@
|
||||
./apps/browser/src/safari/safari/Info.plist
|
||||
./apps/browser/src/safari/desktop.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
|
||||
./SECURITY.md
|
||||
./libs/nx-plugin/src/generators/files/README.md__tmpl__
|
||||
|
||||
50
.github/workflows/alert-ddg-files-modified.yml
vendored
Normal file
50
.github/workflows/alert-ddg-files-modified.yml
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
name: DDG File Change Monitor
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
types: [ opened, synchronize ]
|
||||
|
||||
jobs:
|
||||
check-files:
|
||||
name: Check files
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get changed files
|
||||
id: changed-files
|
||||
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
|
||||
with:
|
||||
list-files: shell
|
||||
filters: |
|
||||
monitored:
|
||||
- 'apps/desktop/native-messaging-test-runner/**'
|
||||
- 'apps/desktop/src/services/duckduckgo-message-handler.service.ts'
|
||||
- 'apps/desktop/src/services/encrypted-message-handler.service.ts'
|
||||
|
||||
- name: Comment on PR if monitored files changed
|
||||
if: steps.changed-files.outputs.monitored == 'true'
|
||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
||||
with:
|
||||
script: |
|
||||
const changedFiles = `${{ steps.changed-files.outputs.monitored_files }}`.split(' ').filter(file => file.trim() !== '');
|
||||
|
||||
const message = `⚠️🦆 **DuckDuckGo Integration files have been modified in this PR:**
|
||||
|
||||
${changedFiles.map(file => `- \`${file}\``).join('\n')}
|
||||
|
||||
Please run the DuckDuckGo native messaging test runner from this branch using [these instructions](https://contributing.bitwarden.com/getting-started/clients/desktop/native-messaging-test-runner) and ensure it functions properly.`;
|
||||
|
||||
github.rest.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: message
|
||||
});
|
||||
5
.github/workflows/auto-branch-updater.yml
vendored
5
.github/workflows/auto-branch-updater.yml
vendored
@@ -1,4 +1,3 @@
|
||||
---
|
||||
name: Auto Update Branch
|
||||
|
||||
on:
|
||||
@@ -23,13 +22,15 @@ jobs:
|
||||
env:
|
||||
_BOT_EMAIL: 106330231+bitwarden-devops-bot@users.noreply.github.com
|
||||
_BOT_NAME: bitwarden-devops-bot
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Setup
|
||||
id: setup
|
||||
run: echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
ref: 'eu-web-${{ steps.setup.outputs.branch }}'
|
||||
fetch-depth: 0
|
||||
|
||||
115
.github/workflows/auto-reply-discussions.yml
vendored
Normal file
115
.github/workflows/auto-reply-discussions.yml
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
name: Auto-reply to Discussions
|
||||
|
||||
on:
|
||||
discussion:
|
||||
types: created
|
||||
|
||||
jobs:
|
||||
reply:
|
||||
name: Auto-reply
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
discussions: write
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Get discussion label and template name
|
||||
id: discussion-label
|
||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
||||
with:
|
||||
script: |
|
||||
const discussion = context.payload.discussion;
|
||||
const template_name = discussion.category.slug;
|
||||
const label = discussion.labels?.[0]?.name ?? '';
|
||||
console.log('Discussion label:', label);
|
||||
console.log('Discussion category slug:', template_name);
|
||||
|
||||
core.setOutput('label', label);
|
||||
core.setOutput('template_name', template_name);
|
||||
|
||||
- name: Get selected topic
|
||||
id: get_selected_topic
|
||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
||||
with:
|
||||
result-encoding: string
|
||||
script: |
|
||||
try {
|
||||
const body = context.payload.discussion.body;
|
||||
const match = body.match(/### Select Topic Area\n\n(.*?)\n\n/);
|
||||
console.log('Match:', match);
|
||||
console.log('Match1:', match[1]);
|
||||
return match ? match[1].trim() : "";
|
||||
} catch (error) {
|
||||
console.error('Error getting selected topic:', error);
|
||||
return "";
|
||||
}
|
||||
|
||||
- name: Reply or close Discussion
|
||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
||||
env:
|
||||
TEMPLATE_NAME: ${{ steps.discussion-label.outputs.template_name }}
|
||||
TOPIC: ${{ steps.get_selected_topic.outputs.result }}
|
||||
with:
|
||||
script: |
|
||||
async function addComment(discussionId, body) {
|
||||
await github.graphql(`
|
||||
mutation AddDiscussionComment($discussionId: ID!, $body: String!) {
|
||||
addDiscussionComment(input: {discussionId: $discussionId, body: $body}) {
|
||||
comment {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`, {
|
||||
discussionId,
|
||||
body
|
||||
});
|
||||
}
|
||||
|
||||
async function closeDiscussion(discussionId) {
|
||||
await github.graphql(`
|
||||
mutation {
|
||||
closeDiscussion(input: {discussionId: "${discussionId}"}) {
|
||||
discussion {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
console.log('♻️ Closing discussion');
|
||||
}
|
||||
|
||||
const discussion = context.payload.discussion;
|
||||
const isFeatureRequest = process.env.TEMPLATE_NAME === 'feature-request';
|
||||
const isTopicEmpty = !process.env.TOPIC || process.env.TOPIC.trim() === ''; // topic step may have failed
|
||||
const isCodeTopic = process.env.TOPIC.includes('Code Contribution Proposal');
|
||||
const shouldClose = isFeatureRequest || (!isTopicEmpty && !isCodeTopic);
|
||||
|
||||
console.log('Template name:', process.env.TEMPLATE_NAME);
|
||||
console.log('Topic:', process.env.TOPIC);
|
||||
console.log('isTopicEmpty:', isTopicEmpty);
|
||||
console.log('isCodeTopic:', isCodeTopic);
|
||||
console.log('shouldClose:', shouldClose);
|
||||
|
||||
if (shouldClose) {
|
||||
const closeMessage =
|
||||
"Thank you for your contribution! GitHub Discussions is specifically for [proposing code](https://contributing.bitwarden.com/) that you would like to write for the Bitwarden codebase. Since this post does not appear to include a proposal, it will be closed. If you believe this was done in error or have any questions, please feel free to reach out to us!\n\n" +
|
||||
"- :bulb: For feature requests and general discussions, please visit the [Bitwarden Community Forums](https://community.bitwarden.com/).\n" +
|
||||
"- :information_source: For questions and support, visit the [Bitwarden Help Center](https://bitwarden.com/help/).\n" +
|
||||
"- :bug: To report a potential bug, please visit the appropriate repository: [Server](https://github.com/bitwarden/server/issues) | [Clients](https://github.com/bitwarden/clients/issues) | [iOS](https://github.com/bitwarden/ios/issues) | [Android](https://github.com/bitwarden/android/issues).";
|
||||
|
||||
await addComment(discussion.node_id, closeMessage);
|
||||
await closeDiscussion(discussion.node_id);
|
||||
return;
|
||||
}
|
||||
|
||||
const replyMessage =
|
||||
":sparkles: Thank you for your code contribution proposal! While the Bitwarden team reviews your submission, we encourage you to check out our [contribution guidelines](https://contributing.bitwarden.com/).\n\n" +
|
||||
"Please ensure that your code contribution includes a detailed description of what you would like to contribute, along with any relevant screenshots and links to existing feature requests. This information helps us gather feedback from the community and Bitwarden team members before you start writing code.\n\n" +
|
||||
"To keep discussions focused, posts that do not include a proposal for a code contribution will be removed.\n\n" +
|
||||
"- :bulb: For feature requests and general discussion, please visit the [Bitwarden Community Forums](https://community.bitwarden.com/).\n" +
|
||||
"- :information_source: For questions and support, visit the [Bitwarden Help Center](https://bitwarden.com/help/).\n" +
|
||||
"- :bug: To report a potential bug, please visit the corresponding repo. [Server](https://github.com/bitwarden/server/issues) | [Clients](https://github.com/bitwarden/clients/issues) | [iOS](https://github.com/bitwarden/ios/issues) | [Android](https://github.com/bitwarden/android/issues)\n\n" +
|
||||
"Thank you for contributing to Bitwarden!";
|
||||
|
||||
await addComment(discussion.node_id, replyMessage);
|
||||
@@ -1,4 +1,3 @@
|
||||
---
|
||||
name: Automatic issue responses
|
||||
on:
|
||||
issues:
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
---
|
||||
name: Automatic pull request responses
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
41
.github/workflows/brew-bump-cli.yml
vendored
41
.github/workflows/brew-bump-cli.yml
vendored
@@ -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-13
|
||||
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: "brew-bump-workflow-pat"
|
||||
|
||||
- name: Update Homebrew formula
|
||||
uses: dawidd6/action-homebrew-bump-formula@baf2b60c51fc1f8453c884b0c61052668a71bd1d # v3.11.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
|
||||
42
.github/workflows/brew-bump-desktop.yml
vendored
42
.github/workflows/brew-bump-desktop.yml
vendored
@@ -1,42 +0,0 @@
|
||||
---
|
||||
name: Bump Desktop Cask
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- desktop-v**
|
||||
workflow_dispatch:
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
update-desktop-cask:
|
||||
name: Update Bitwarden Desktop Cask
|
||||
runs-on: macos-13
|
||||
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: "brew-bump-workflow-pat"
|
||||
|
||||
- name: Update Homebrew cask
|
||||
uses: macauley/action-homebrew-bump-cask@445c42390d790569d938f9068d01af39ca030feb # v1.0.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-cask
|
||||
cask: bitwarden
|
||||
tag: ${{ github.ref }}
|
||||
revision: ${{ github.sha }}
|
||||
force: true
|
||||
dryrun: true
|
||||
44
.github/workflows/build-browser-target.yml
vendored
Normal file
44
.github/workflows/build-browser-target.yml
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
# This workflow is intended to be run when we need to build the client and produce artifacts that require secrets
|
||||
# when the PR source branch does not have access to secrets (e.g. a fork).
|
||||
# This workflow will run in the context of the target of the PR and have access to secrets.
|
||||
# This should only be done after reviewing the PR to ensure that no malicious code has been introduced,
|
||||
# as it could allow the code on the forked branch to have access to workflow secrets.
|
||||
|
||||
name: Build Browser on PR Target
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened]
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'apps/browser/**'
|
||||
- 'libs/**'
|
||||
- '*'
|
||||
- '!*.md'
|
||||
- '!*.txt'
|
||||
workflow_call:
|
||||
inputs: {}
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
check-run:
|
||||
name: Check PR run
|
||||
uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
run-workflow:
|
||||
name: Build Browser
|
||||
needs: check-run
|
||||
if: ${{ github.event.pull_request.head.repo.full_name != github.repository }}
|
||||
uses: ./.github/workflows/build-browser.yml
|
||||
secrets: inherit
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
id-token: write
|
||||
|
||||
352
.github/workflows/build-browser.yml
vendored
352
.github/workflows/build-browser.yml
vendored
@@ -1,8 +1,12 @@
|
||||
---
|
||||
# This workflow will run in the context of the source of the PR.
|
||||
# On a PR from a fork, the workflow will not have access to secrets, and so any parts of the build that require secrets will not run.
|
||||
# If additional artifacts are needed, the failed "build-browser-target.yml" workflow held up by the check-run should be re-run.
|
||||
|
||||
name: Build Browser
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
branches-ignore:
|
||||
- 'l10n_master'
|
||||
- 'cf-pages'
|
||||
@@ -27,12 +31,19 @@ on:
|
||||
workflow_call:
|
||||
inputs: {}
|
||||
workflow_dispatch:
|
||||
inputs: {}
|
||||
inputs:
|
||||
sdk_branch:
|
||||
description: "Custom SDK branch"
|
||||
required: false
|
||||
type: string
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
name: Setup
|
||||
@@ -41,9 +52,12 @@ jobs:
|
||||
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 }}
|
||||
has_secrets: ${{ steps.check-secrets.outputs.has_secrets }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- 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
|
||||
@@ -62,6 +76,12 @@ jobs:
|
||||
NODE_VERSION=${NODE_NVMRC/v/''}
|
||||
echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Check secrets
|
||||
id: check-secrets
|
||||
run: |
|
||||
has_secrets=${{ secrets.AZURE_CLIENT_ID != '' }}
|
||||
echo "has_secrets=$has_secrets" >> $GITHUB_OUTPUT
|
||||
|
||||
|
||||
locales-test:
|
||||
name: Locales Test
|
||||
@@ -72,8 +92,10 @@ jobs:
|
||||
run:
|
||||
working-directory: apps/browser
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- 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: |
|
||||
@@ -100,8 +122,8 @@ jobs:
|
||||
fi
|
||||
|
||||
|
||||
build:
|
||||
name: Build
|
||||
build-source:
|
||||
name: Build browser source
|
||||
runs-on: ubuntu-22.04
|
||||
needs:
|
||||
- setup
|
||||
@@ -110,11 +132,13 @@ jobs:
|
||||
_BUILD_NUMBER: ${{ needs.setup.outputs.adj_build_number }}
|
||||
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- 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@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
||||
with:
|
||||
cache: 'npm'
|
||||
cache-dependency-path: '**/package-lock.json'
|
||||
@@ -138,10 +162,6 @@ jobs:
|
||||
FILES=$(find . -maxdepth 1 -type f)
|
||||
for FILE in $FILES; do cp "$FILE" browser-source/; done
|
||||
|
||||
# Copy patches to the Browser source directory
|
||||
mkdir -p browser-source/patches
|
||||
cp -r patches/* browser-source/patches
|
||||
|
||||
# Copy apps/browser to the Browser source directory
|
||||
mkdir -p browser-source/apps/browser
|
||||
cp -r apps/browser/* browser-source/apps/browser
|
||||
@@ -152,101 +172,55 @@ 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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
with:
|
||||
name: coverage-${{ env._BUILD_NUMBER }}.zip
|
||||
path: browser-source/apps/browser/coverage/coverage-${{ env._BUILD_NUMBER }}.zip
|
||||
if-no-files-found: error
|
||||
|
||||
build-safari:
|
||||
name: Build Safari
|
||||
runs-on: macos-13
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-22.04
|
||||
needs:
|
||||
- setup
|
||||
- locales-test
|
||||
- build-source
|
||||
env:
|
||||
_BUILD_NUMBER: ${{ needs.setup.outputs.adj_build_number }}
|
||||
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- name: "chrome"
|
||||
npm_command: "dist:chrome"
|
||||
archive_name: "dist-chrome.zip"
|
||||
artifact_name: "dist-chrome-MV3"
|
||||
- name: "edge"
|
||||
npm_command: "dist:edge"
|
||||
archive_name: "dist-edge.zip"
|
||||
artifact_name: "dist-edge-MV3"
|
||||
- name: "firefox"
|
||||
npm_command: "dist:firefox"
|
||||
archive_name: "dist-firefox.zip"
|
||||
artifact_name: "dist-firefox"
|
||||
- name: "firefox-mv3"
|
||||
npm_command: "dist:firefox:mv3"
|
||||
archive_name: "dist-firefox.zip"
|
||||
artifact_name: "DO-NOT-USE-FOR-PROD-dist-firefox-MV3"
|
||||
- name: "opera-mv3"
|
||||
npm_command: "dist:opera:mv3"
|
||||
archive_name: "dist-opera.zip"
|
||||
artifact_name: "dist-opera-MV3"
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- 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@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
||||
with:
|
||||
cache: 'npm'
|
||||
cache-dependency-path: '**/package-lock.json'
|
||||
@@ -257,10 +231,117 @@ jobs:
|
||||
node --version
|
||||
npm --version
|
||||
|
||||
- name: Login to Azure
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
- name: Download browser source
|
||||
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
name: browser-source-${{ env._BUILD_NUMBER }}.zip
|
||||
|
||||
- name: Unzip browser source artifact
|
||||
run: |
|
||||
unzip browser-source.zip
|
||||
rm browser-source.zip
|
||||
|
||||
- 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:
|
||||
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: Check source file size
|
||||
if: ${{ startsWith(matrix.name, 'firefox') }}
|
||||
run: |
|
||||
# Declare variable as indexed array
|
||||
declare -a FILES
|
||||
|
||||
# Search for source files that are greater than 4M
|
||||
TARGET_DIR='./browser-source/apps/browser'
|
||||
while IFS=' ' read -r RESULT; do
|
||||
FILES+=("$RESULT")
|
||||
done < <(find $TARGET_DIR -size +4M)
|
||||
|
||||
# Validate results and provide messaging
|
||||
if [[ ${#FILES[@]} -ne 0 ]]; then
|
||||
echo "File(s) exceeds size limit: 4MB"
|
||||
for FILE in ${FILES[@]}; do
|
||||
echo "- $(du --si $FILE)"
|
||||
done
|
||||
echo "ERROR Firefox rejects extension uploads that contain files larger than 4MB"
|
||||
# Invoke failure
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Build extension
|
||||
run: npm run ${{ matrix.npm_command }}
|
||||
working-directory: browser-source/apps/browser
|
||||
|
||||
- name: Upload extension artifact
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
with:
|
||||
name: ${{ matrix.artifact_name }}-${{ env._BUILD_NUMBER }}.zip
|
||||
path: browser-source/apps/browser/dist/${{ matrix.archive_name }}
|
||||
if-no-files-found: error
|
||||
|
||||
|
||||
build-safari:
|
||||
name: Build Safari
|
||||
runs-on: macos-13
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
needs:
|
||||
- setup
|
||||
- locales-test
|
||||
if: ${{ needs.setup.outputs.has_secrets == 'true' }}
|
||||
env:
|
||||
_BUILD_NUMBER: ${{ needs.setup.outputs.adj_build_number }}
|
||||
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
|
||||
steps:
|
||||
- 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@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
||||
with:
|
||||
cache: 'npm'
|
||||
cache-dependency-path: '**/package-lock.json'
|
||||
node-version: ${{ env._NODE_VERSION }}
|
||||
|
||||
- name: Print environment
|
||||
run: |
|
||||
node --version
|
||||
npm --version
|
||||
|
||||
- name: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Get Azure Key Vault secrets
|
||||
id: get-kv-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: gh-clients
|
||||
secrets: "KEYCHAIN-PASSWORD"
|
||||
|
||||
- name: Download Provisioning Profiles secrets
|
||||
env:
|
||||
@@ -296,9 +377,12 @@ jobs:
|
||||
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: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- name: Set up keychain
|
||||
env:
|
||||
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
|
||||
KEYCHAIN_PASSWORD: ${{ steps.get-kv-secrets.outputs.KEYCHAIN-PASSWORD }}
|
||||
run: |
|
||||
security create-keychain -p $KEYCHAIN_PASSWORD build.keychain
|
||||
security default-keychain -s build.keychain
|
||||
@@ -329,6 +413,25 @@ 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: |
|
||||
npm link ../sdk-internal
|
||||
|
||||
- name: Build Safari extension
|
||||
run: npm run dist:safari
|
||||
working-directory: apps/browser
|
||||
@@ -341,7 +444,7 @@ jobs:
|
||||
ls -la
|
||||
|
||||
- name: Upload Safari artifact
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
with:
|
||||
name: dist-safari-${{ env._BUILD_NUMBER }}.zip
|
||||
path: apps/browser/dist/dist-safari.zip
|
||||
@@ -349,19 +452,27 @@ jobs:
|
||||
|
||||
crowdin-push:
|
||||
name: Crowdin Push
|
||||
if: github.ref == 'refs/heads/main'
|
||||
if: github.event_name != 'pull_request_target' && github.ref == 'refs/heads/main'
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
id-token: write
|
||||
needs:
|
||||
- build
|
||||
- build-safari
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- name: Login to Azure
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
@@ -370,8 +481,11 @@ jobs:
|
||||
keyvault: "bitwarden-ci"
|
||||
secrets: "crowdin-api-token"
|
||||
|
||||
- name: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- name: Upload Sources
|
||||
uses: crowdin/github-action@c953b17499daa6be3e5afbf7a63616fb02d8b18d # v1.19.0
|
||||
uses: crowdin/github-action@f214c8723025f41fc55b2ad26e67b60b80b1885d # v2.7.1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
|
||||
@@ -382,26 +496,36 @@ jobs:
|
||||
upload_sources: true
|
||||
upload_translations: false
|
||||
|
||||
|
||||
check-failures:
|
||||
name: Check for failures
|
||||
if: always()
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
needs:
|
||||
- setup
|
||||
- locales-test
|
||||
- build-source
|
||||
- build
|
||||
- build-safari
|
||||
- crowdin-push
|
||||
steps:
|
||||
- name: Check if any job failed
|
||||
if: (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc') && contains(needs.*.result, 'failure')
|
||||
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@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
- name: Log in to Azure
|
||||
if: failure()
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
@@ -411,8 +535,12 @@ jobs:
|
||||
keyvault: "bitwarden-ci"
|
||||
secrets: "devops-alerts-slack-webhook-url"
|
||||
|
||||
- name: Log out from Azure
|
||||
if: failure()
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- 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 }}
|
||||
|
||||
43
.github/workflows/build-cli-target.yml
vendored
Normal file
43
.github/workflows/build-cli-target.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
# This workflow is intended to be run when we need to build the client and produce artifacts that require secrets
|
||||
# when the PR source branch does not have access to secrets (e.g. a fork).
|
||||
# This workflow will run in the context of the target of the PR and have access to secrets.
|
||||
# This should only be done after reviewing the PR to ensure that no malicious code has been introduced,
|
||||
# as it could allow the code on the forked branch to have access to workflow secrets.
|
||||
|
||||
name: Build CLI on PR Target
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened]
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'apps/cli/**'
|
||||
- 'libs/**'
|
||||
- '*'
|
||||
- '!*.md'
|
||||
- '!*.txt'
|
||||
- '.github/workflows/build-cli.yml'
|
||||
- 'bitwarden_license/bit-cli/**'
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
check-run:
|
||||
name: Check PR run
|
||||
uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
run-workflow:
|
||||
name: Build CLI
|
||||
needs: check-run
|
||||
if: ${{ github.event.pull_request.head.repo.full_name != github.repository }}
|
||||
uses: ./.github/workflows/build-cli.yml
|
||||
secrets: inherit
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
|
||||
383
.github/workflows/build-cli.yml
vendored
383
.github/workflows/build-cli.yml
vendored
@@ -1,13 +1,19 @@
|
||||
---
|
||||
# This workflow will run in the context of the source of the PR.
|
||||
# On a PR from a fork, the workflow will not have access to secrets, and so any parts of the build that require secrets will not run.
|
||||
# If additional artifacts are needed, the failed "build-cli-target.yml" workflow held up by the check-run should be re-run.
|
||||
|
||||
name: Build CLI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
branches-ignore:
|
||||
- 'l10n_master'
|
||||
- 'cf-pages'
|
||||
paths:
|
||||
- 'apps/cli/**'
|
||||
- 'bitwarden_license/bit-cli/**'
|
||||
- 'bitwarden_license/bit-common/**'
|
||||
- 'libs/**'
|
||||
- '*'
|
||||
- '!*.md'
|
||||
@@ -20,28 +26,42 @@ on:
|
||||
- 'hotfix-rc-cli'
|
||||
paths:
|
||||
- 'apps/cli/**'
|
||||
- 'bitwarden_license/bit-cli/**'
|
||||
- 'bitwarden_license/bit-common/**'
|
||||
- 'libs/**'
|
||||
- '*'
|
||||
- '!*.md'
|
||||
- '!*.txt'
|
||||
- '.github/workflows/build-cli.yml'
|
||||
workflow_dispatch:
|
||||
workflow_call:
|
||||
inputs: {}
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
sdk_branch:
|
||||
description: "Custom SDK branch"
|
||||
required: false
|
||||
type: string
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: apps/cli
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
name: Setup
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
outputs:
|
||||
package_version: ${{ steps.retrieve-package-version.outputs.package_version }}
|
||||
node_version: ${{ steps.retrieve-node-version.outputs.node_version }}
|
||||
has_secrets: ${{ steps.check-secrets.outputs.has_secrets }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- 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-package-version
|
||||
@@ -51,29 +71,50 @@ jobs:
|
||||
|
||||
- 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
|
||||
|
||||
- name: Check secrets
|
||||
id: check-secrets
|
||||
run: |
|
||||
has_secrets=${{ secrets.AZURE_CLIENT_ID != '' }}
|
||||
echo "has_secrets=$has_secrets" >> $GITHUB_OUTPUT
|
||||
|
||||
|
||||
cli:
|
||||
name: Build CLI ${{ matrix.os }}
|
||||
name: CLI ${{ matrix.os.base }}${{ matrix.os.target_suffix }} - ${{ matrix.license_type.readable }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-22.04, macos-11]
|
||||
runs-on: ${{ matrix.os }}
|
||||
needs:
|
||||
- setup
|
||||
os:
|
||||
[
|
||||
{ base: "linux", distro: "ubuntu-22.04", target_suffix: "" },
|
||||
{ base: "linux", distro: "ubuntu-22.04-arm", target_suffix: "-arm64" },
|
||||
{ base: "mac", distro: "macos-13", target_suffix: "" },
|
||||
{ base: "mac", distro: "macos-14", target_suffix: "-arm64" }
|
||||
]
|
||||
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 }}
|
||||
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
|
||||
_WIN_PKG_FETCH_VERSION: 18.5.0
|
||||
_WIN_PKG_VERSION: 3.4
|
||||
_WIN_PKG_FETCH_VERSION: 20.11.1
|
||||
_WIN_PKG_VERSION: 3.5
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: Setup Unix Vars
|
||||
run: |
|
||||
@@ -82,7 +123,7 @@ jobs:
|
||||
awk '{print tolower($0)}')" >> $GITHUB_ENV
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
||||
with:
|
||||
cache: 'npm'
|
||||
cache-dependency-path: '**/package-lock.json'
|
||||
@@ -92,17 +133,108 @@ jobs:
|
||||
run: npm ci
|
||||
working-directory: ./
|
||||
|
||||
- name: Download SDK Artifacts
|
||||
if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }}
|
||||
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 != '' && needs.setup.outputs.has_secrets == 'true' }}
|
||||
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 }}${{ matrix.os.target_suffix }} --quiet
|
||||
|
||||
- name: Login to Azure
|
||||
if: ${{ matrix.os.base == 'mac' && needs.setup.outputs.has_secrets == 'true' }}
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Get certificates
|
||||
if: ${{ matrix.os.base == 'mac' && needs.setup.outputs.has_secrets == 'true' }}
|
||||
run: |
|
||||
mkdir -p $HOME/certificates
|
||||
|
||||
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
|
||||
|
||||
- name: Get Azure Key Vault secrets
|
||||
id: get-kv-secrets
|
||||
if: ${{ matrix.os.base == 'mac' && needs.setup.outputs.has_secrets == 'true' }}
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: gh-clients
|
||||
secrets: "KEYCHAIN-PASSWORD,APP-STORE-CONNECT-AUTH-KEY,APP-STORE-CONNECT-TEAM-ISSUER"
|
||||
|
||||
- name: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- name: Set up keychain
|
||||
if: ${{ matrix.os.base == 'mac' && needs.setup.outputs.has_secrets == 'true' }}
|
||||
env:
|
||||
KEYCHAIN_PASSWORD: ${{ steps.get-kv-secrets.outputs.KEYCHAIN-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/certificates/devid-app-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: Sign binary
|
||||
if: ${{ matrix.os.base == 'mac' && needs.setup.outputs.has_secrets == 'true' }}
|
||||
env:
|
||||
MACOS_CERTIFICATE_NAME: "Developer ID Application: 8bit Solutions LLC"
|
||||
run: codesign --sign "$MACOS_CERTIFICATE_NAME" --verbose=3 --force --options=runtime --entitlements ./entitlements.plist --timestamp ./dist/${{ matrix.license_type.build_prefix }}/${{ env.LOWER_RUNNER_OS }}${{ matrix.os.target_suffix }}/bw
|
||||
|
||||
- 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 }}${{ matrix.os.target_suffix }}
|
||||
zip ../../bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}${{ matrix.os.target_suffix }}-${{ env._PACKAGE_VERSION }}.zip ./bw
|
||||
|
||||
- name: Set up private auth key
|
||||
if: ${{ matrix.os.base == 'mac' && needs.setup.outputs.has_secrets == 'true' }}
|
||||
run: |
|
||||
mkdir ~/private_keys
|
||||
cat << EOF > ~/private_keys/AuthKey_6TV9MKN3GP.p8
|
||||
${{ steps.get-kv-secrets.outputs.APP-STORE-CONNECT-AUTH-KEY }}
|
||||
EOF
|
||||
|
||||
- name: Notarize app
|
||||
if: ${{ matrix.os.base == 'mac' && needs.setup.outputs.has_secrets == 'true' }}
|
||||
env:
|
||||
APP_STORE_CONNECT_TEAM_ISSUER: ${{ steps.get-kv-secrets.outputs.APP-STORE-CONNECT-TEAM-ISSUER }}
|
||||
APP_STORE_CONNECT_AUTH_KEY: 6TV9MKN3GP
|
||||
APP_STORE_CONNECT_AUTH_KEY_PATH: ~/private_keys/AuthKey_6TV9MKN3GP.p8
|
||||
run: |
|
||||
echo "Create keychain profile"
|
||||
xcrun notarytool store-credentials "notarytool-profile" --key-id "$APP_STORE_CONNECT_AUTH_KEY" --key "$APP_STORE_CONNECT_AUTH_KEY_PATH" --issuer "$APP_STORE_CONNECT_TEAM_ISSUER"
|
||||
|
||||
codesign --sign "Developer ID Application: 8bit Solutions LLC" --verbose=3 --force --options=runtime --timestamp ./dist/bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}${{ matrix.os.target_suffix }}-${{ env._PACKAGE_VERSION }}.zip
|
||||
|
||||
echo "Notarize app"
|
||||
xcrun notarytool submit ./dist/bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}${{ matrix.os.target_suffix }}-${{ env._PACKAGE_VERSION }}.zip --keychain-profile "notarytool-profile" --wait
|
||||
|
||||
- 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 }}${{ matrix.os.target_suffix }}-${{ env._PACKAGE_VERSION }}.zip" -d "./test"
|
||||
testVersion=$(./test/bw -v)
|
||||
echo "version: $_PACKAGE_VERSION"
|
||||
echo "testVersion: $testVersion"
|
||||
@@ -111,39 +243,56 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- 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
|
||||
|
||||
- name: Upload unix zip asset
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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 }}${{ matrix.os.target_suffix }}-${{ env._PACKAGE_VERSION }}.zip
|
||||
path: apps/cli/dist/bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}${{ matrix.os.target_suffix }}-${{ env._PACKAGE_VERSION }}.zip
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload unix checksum asset
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
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
|
||||
if-no-files-found: error
|
||||
# We want to confirm the CLI is runnable using the dependencies defined in `apps/cli/package.json`.
|
||||
- name: Remove node_modules (root)
|
||||
run: rm -rf node_modules
|
||||
working-directory: ./
|
||||
|
||||
- name: Remove package.json (root)
|
||||
run: rm package.json
|
||||
working-directory: ./
|
||||
|
||||
- name: Install (CLI)
|
||||
run: npm i
|
||||
|
||||
- name: Output help
|
||||
run: node ./build/bw.js --help
|
||||
|
||||
|
||||
cli-windows:
|
||||
name: Build CLI Windows
|
||||
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
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
needs: setup
|
||||
env:
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
|
||||
_WIN_PKG_FETCH_VERSION: 18.5.0
|
||||
_WIN_PKG_VERSION: 3.4
|
||||
_WIN_PKG_FETCH_VERSION: 20.11.1
|
||||
_WIN_PKG_VERSION: 3.5
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: Install AST
|
||||
run: dotnet tool install --global AzureSignTool --version 4.0.1
|
||||
|
||||
- name: Setup Windows builder
|
||||
run: |
|
||||
@@ -152,7 +301,7 @@ jobs:
|
||||
choco install nasm --no-progress
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
||||
with:
|
||||
cache: 'npm'
|
||||
cache-dependency-path: '**/package-lock.json'
|
||||
@@ -162,7 +311,7 @@ jobs:
|
||||
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 `
|
||||
@@ -213,67 +362,117 @@ jobs:
|
||||
ResourceHacker -open version-info.rc -save version-info.res -action compile
|
||||
ResourceHacker -open %WIN_PKG_BUILT% -save %WIN_PKG_BUILT% -action addoverwrite -resource version-info.res
|
||||
|
||||
- name: Log in to Azure
|
||||
if: ${{ needs.setup.outputs.has_secrets == 'true' }}
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
if: ${{ needs.setup.outputs.has_secrets == 'true' }}
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: "bitwarden-ci"
|
||||
secrets: "code-signing-vault-url,
|
||||
code-signing-client-id,
|
||||
code-signing-tenant-id,
|
||||
code-signing-client-secret,
|
||||
code-signing-cert-name"
|
||||
|
||||
- name: Log out from Azure
|
||||
if: ${{ needs.setup.outputs.has_secrets == 'true' }}
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- name: Install
|
||||
run: npm ci
|
||||
working-directory: ./
|
||||
|
||||
- name: Download SDK Artifacts
|
||||
if: ${{ inputs.sdk_branch != '' && needs.setup.outputs.has_secrets == 'true' }}
|
||||
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 != '' && needs.setup.outputs.has_secrets == 'true' }}
|
||||
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: Sign executable
|
||||
if: ${{ needs.setup.outputs.has_secrets == 'true' }}
|
||||
shell: pwsh
|
||||
env:
|
||||
SIGNING_VAULT_URL: ${{ steps.retrieve-secrets.outputs.code-signing-vault-url }}
|
||||
SIGNING_CLIENT_ID: ${{ steps.retrieve-secrets.outputs.code-signing-client-id }}
|
||||
SIGNING_TENANT_ID: ${{ steps.retrieve-secrets.outputs.code-signing-tenant-id }}
|
||||
SIGNING_CLIENT_SECRET: ${{ steps.retrieve-secrets.outputs.code-signing-client-secret }}
|
||||
SIGNING_CERT_NAME: ${{ steps.retrieve-secrets.outputs.code-signing-cert-name }}
|
||||
EXE_PATH: dist/${{ matrix.license_type.build_prefix }}/windows/bw.exe
|
||||
run: . .\scripts\sign-cli.ps1
|
||||
|
||||
- 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) {
|
||||
Throw "Version test failed."
|
||||
}
|
||||
|
||||
- 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
|
||||
|
||||
- name: Upload windows zip asset
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
with:
|
||||
name: bw-windows-${{ env._PACKAGE_VERSION }}.zip
|
||||
path: apps/cli/dist/bw-windows-${{ env._PACKAGE_VERSION }}.zip
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload windows checksum asset
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
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-${{ 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 Chocolatey asset
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
if: matrix.license_type.build_prefix == 'bit'
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
if: matrix.license_type.build_prefix == 'bit'
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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:
|
||||
@@ -286,8 +485,10 @@ jobs:
|
||||
env:
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: Print environment
|
||||
run: |
|
||||
@@ -297,7 +498,7 @@ jobs:
|
||||
echo "BW Package Version: $_PACKAGE_VERSION"
|
||||
|
||||
- name: Get bw linux cli
|
||||
uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
|
||||
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
|
||||
with:
|
||||
name: bw-linux-${{ env._PACKAGE_VERSION }}.zip
|
||||
path: apps/cli/dist/snap
|
||||
@@ -310,17 +511,10 @@ jobs:
|
||||
ls -alth
|
||||
|
||||
- name: Build snap
|
||||
uses: snapcore/action-build@2096990827aa966f773676c8a53793c723b6b40f # v1.2.0
|
||||
uses: snapcore/action-build@3bdaa03e1ba6bf59a65f84a751d943d549a54e79 # v1.3.0
|
||||
with:
|
||||
path: apps/cli/dist/snap
|
||||
|
||||
- name: Create checksum
|
||||
run: |
|
||||
cd dist/snap
|
||||
ls -alth
|
||||
sha256sum bw_${{ env._PACKAGE_VERSION }}_amd64.snap \
|
||||
| awk '{split($0, a); print a[1]}' > bw-snap-sha256-${{ env._PACKAGE_VERSION }}.txt
|
||||
|
||||
- name: Install Snap
|
||||
run: sudo snap install dist/snap/bw*.snap --dangerous
|
||||
|
||||
@@ -339,24 +533,20 @@ jobs:
|
||||
run: sudo snap remove bw
|
||||
|
||||
- name: Upload snap asset
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
with:
|
||||
name: bw-snap-sha256-${{ env._PACKAGE_VERSION }}.txt
|
||||
path: apps/cli/dist/snap/bw-snap-sha256-${{ env._PACKAGE_VERSION }}.txt
|
||||
if-no-files-found: error
|
||||
|
||||
|
||||
check-failures:
|
||||
name: Check for failures
|
||||
if: always()
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
needs:
|
||||
- setup
|
||||
- cli
|
||||
@@ -365,14 +555,19 @@ jobs:
|
||||
steps:
|
||||
- name: Check if any job failed
|
||||
working-directory: ${{ github.workspace }}
|
||||
if: (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc') && contains(needs.*.result, 'failure')
|
||||
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@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
- name: Log in to Azure
|
||||
if: failure()
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
@@ -382,8 +577,12 @@ jobs:
|
||||
keyvault: "bitwarden-ci"
|
||||
secrets: "devops-alerts-slack-webhook-url"
|
||||
|
||||
- name: Log out from Azure
|
||||
if: failure()
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- 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 }}
|
||||
|
||||
44
.github/workflows/build-desktop-target.yml
vendored
Normal file
44
.github/workflows/build-desktop-target.yml
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
|
||||
# This workflow is intended to be run when we need to build the client and produce artifacts that require secrets
|
||||
# when the PR source branch does not have access to secrets (e.g. a fork).
|
||||
# This workflow will run in the context of the target of the PR and have access to secrets.
|
||||
# This should only be done after reviewing the PR to ensure that no malicious code has been introduced,
|
||||
# as it could allow the code on the forked branch to have access to workflow secrets.
|
||||
|
||||
name: Build Desktop on PR Target
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened]
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'apps/desktop/**'
|
||||
- 'libs/**'
|
||||
- '*'
|
||||
- '!*.md'
|
||||
- '!*.txt'
|
||||
- '.github/workflows/build-desktop.yml'
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
check-run:
|
||||
name: Check PR run
|
||||
uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
run-workflow:
|
||||
name: Build Desktop
|
||||
needs: check-run
|
||||
if: ${{ github.event.pull_request.head.repo.full_name != github.repository }}
|
||||
uses: ./.github/workflows/build-desktop.yml
|
||||
secrets: inherit
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
id-token: write
|
||||
|
||||
940
.github/workflows/build-desktop.yml
vendored
940
.github/workflows/build-desktop.yml
vendored
File diff suppressed because it is too large
Load Diff
44
.github/workflows/build-web-target.yml
vendored
Normal file
44
.github/workflows/build-web-target.yml
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
# This workflow is intended to be run when we need to build the client and produce artifacts that require secrets
|
||||
# when the PR source branch does not have access to secrets (e.g. a fork).
|
||||
# This workflow will run in the context of the target of the PR and have access to secrets.
|
||||
# This should only be done after reviewing the PR to ensure that no malicious code has been introduced,
|
||||
# as it could allow the code on the forked branch to have access to workflow secrets.
|
||||
|
||||
name: Build Web on PR Target
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened]
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'apps/web/**'
|
||||
- 'libs/**'
|
||||
- '*'
|
||||
- '!*.md'
|
||||
- '!*.txt'
|
||||
- '.github/workflows/build-web.yml'
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
check-run:
|
||||
name: Check PR run
|
||||
uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
run-workflow:
|
||||
name: Build Web
|
||||
needs: check-run
|
||||
if: ${{ github.event.pull_request.head.repo.full_name != github.repository }}
|
||||
uses: ./.github/workflows/build-web.yml
|
||||
secrets: inherit
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
id-token: write
|
||||
security-events: write
|
||||
|
||||
421
.github/workflows/build-web.yml
vendored
421
.github/workflows/build-web.yml
vendored
@@ -1,13 +1,19 @@
|
||||
---
|
||||
# This workflow will run in the context of the source of the PR.
|
||||
# On a PR from a fork, the workflow will not have access to secrets, and so any parts of the build that require secrets will not run.
|
||||
# If additional artifacts are needed, the failed "build-web-target.yml" workflow held up by the check-run should be re-run.
|
||||
|
||||
name: Build Web
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
branches-ignore:
|
||||
- 'l10n_master'
|
||||
- 'cf-pages'
|
||||
paths:
|
||||
- 'apps/web/**'
|
||||
- 'bitwarden_license/bit-common/**'
|
||||
- 'bitwarden_license/bit-web/**'
|
||||
- 'libs/**'
|
||||
- '*'
|
||||
- '!*.md'
|
||||
@@ -20,6 +26,8 @@ on:
|
||||
- 'hotfix-rc-web'
|
||||
paths:
|
||||
- 'apps/web/**'
|
||||
- 'bitwarden_license/bit-common/**'
|
||||
- 'bitwarden_license/bit-web/**'
|
||||
- 'libs/**'
|
||||
- '*'
|
||||
- '!*.md'
|
||||
@@ -27,25 +35,38 @@ on:
|
||||
- '.github/workflows/build-web.yml'
|
||||
release:
|
||||
types: [published]
|
||||
workflow_call:
|
||||
inputs: {}
|
||||
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
|
||||
_GITHUB_PR_REPO_NAME: ${{ github.event.pull_request.head.repo.full_name }}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
name: Setup
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
outputs:
|
||||
version: ${{ steps.version.outputs.value }}
|
||||
node_version: ${{ steps.retrieve-node-version.outputs.node_version }}
|
||||
has_secrets: ${{ steps.check-secrets.outputs.has_secrets }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- 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
|
||||
@@ -58,106 +79,89 @@ jobs:
|
||||
NODE_VERSION=${NODE_NVMRC/v/''}
|
||||
echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
build-artifacts:
|
||||
name: Build artifacts
|
||||
runs-on: ubuntu-22.04
|
||||
needs: setup
|
||||
env:
|
||||
_VERSION: ${{ needs.setup.outputs.version }}
|
||||
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- name: "selfhosted-open-source"
|
||||
npm_command: "dist:oss:selfhost"
|
||||
- name: "cloud-COMMERCIAL"
|
||||
npm_command: "dist:bit:cloud"
|
||||
- name: "selfhosted-COMMERCIAL"
|
||||
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@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
cache: 'npm'
|
||||
cache-dependency-path: '**/package-lock.json'
|
||||
node-version: ${{ env._NODE_VERSION }}
|
||||
|
||||
- name: Print environment
|
||||
- name: Check secrets
|
||||
id: check-secrets
|
||||
run: |
|
||||
whoami
|
||||
node --version
|
||||
npm --version
|
||||
gulp --version
|
||||
docker --version
|
||||
echo "GitHub ref: $GITHUB_REF"
|
||||
echo "GitHub event: $GITHUB_EVENT"
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Add Git metadata to build version
|
||||
working-directory: apps/web
|
||||
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
|
||||
mv package.json.tmp package.json
|
||||
|
||||
- name: Build ${{ matrix.name }}
|
||||
working-directory: apps/web
|
||||
run: npm run ${{ matrix.npm_command }}
|
||||
|
||||
- name: Package artifact
|
||||
working-directory: apps/web
|
||||
run: zip -r web-${{ env._VERSION }}-${{ matrix.name }}.zip build
|
||||
|
||||
- name: Upload ${{ matrix.name }} artifact
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
with:
|
||||
name: web-${{ env._VERSION }}-${{ matrix.name }}.zip
|
||||
path: apps/web/web-${{ env._VERSION }}-${{ matrix.name }}.zip
|
||||
if-no-files-found: error
|
||||
has_secrets=${{ secrets.AZURE_CLIENT_ID != '' }}
|
||||
echo "has_secrets=$has_secrets" >> $GITHUB_OUTPUT
|
||||
|
||||
|
||||
build-containers:
|
||||
name: Build Docker images
|
||||
runs-on: ubuntu-22.04
|
||||
needs:
|
||||
- setup
|
||||
- build-artifacts
|
||||
name: "Build [${{matrix.artifact_name}}], image tag: [${{matrix.image_name}}]"
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
security-events: write
|
||||
id-token: write
|
||||
needs: setup
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- artifact_name: cloud-QA
|
||||
image_name: web-qa-cloud
|
||||
- artifact_name: ee
|
||||
image_name: web-ee
|
||||
- artifact_name: selfhosted-open-source
|
||||
image_name: web-oss
|
||||
npm_command: dist:oss:selfhost
|
||||
- artifact_name: cloud-COMMERCIAL
|
||||
image_name: web-cloud
|
||||
npm_command: dist:bit:cloud
|
||||
- artifact_name: selfhosted-COMMERCIAL
|
||||
image_name: web
|
||||
npm_command: dist:bit:selfhost
|
||||
- artifact_name: cloud-QA
|
||||
image_name: web-qa-cloud
|
||||
npm_command: build:bit:qa
|
||||
git_metadata: true
|
||||
- artifact_name: ee
|
||||
image_name: web-ee
|
||||
npm_command: build:bit:ee
|
||||
git_metadata: true
|
||||
- artifact_name: cloud-euprd
|
||||
image_name: web-euprd
|
||||
npm_command: build:bit:euprd
|
||||
- artifact_name: cloud-euqa
|
||||
image_name: web-euqa
|
||||
npm_command: build:bit:euqa
|
||||
git_metadata: true
|
||||
- artifact_name: cloud-usdev
|
||||
image_name: web-usdev
|
||||
npm_command: build:bit:usdev
|
||||
git_metadata: true
|
||||
env:
|
||||
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
|
||||
_VERSION: ${{ needs.setup.outputs.version }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: Get Latest Server Version
|
||||
id: latest-server-version
|
||||
uses: bitwarden/gh-actions/get-release-version@main
|
||||
with:
|
||||
repository: bitwarden/server
|
||||
trim: false
|
||||
|
||||
- name: Set Server Ref
|
||||
id: set-server-ref
|
||||
run: |
|
||||
SERVER_REF="${{ steps.latest-server-version.outputs.version }}"
|
||||
echo "Latest server release version: $SERVER_REF"
|
||||
if [[ "$GITHUB_REF" == "refs/heads/main" ]]; then
|
||||
SERVER_REF="$GITHUB_REF"
|
||||
elif [[ "$GITHUB_REF" == "refs/heads/rc" ]]; then
|
||||
SERVER_REF="$GITHUB_REF"
|
||||
elif [[ "$GITHUB_EVENT_NAME" == "pull_request" ]]; then
|
||||
SERVER_REF="refs/heads/main"
|
||||
fi
|
||||
echo "Server ref: $SERVER_REF"
|
||||
echo "server_ref=$SERVER_REF" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Check out Server repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
path: server
|
||||
repository: bitwarden/server
|
||||
ref: ${{ steps.set-server-ref.outputs.server_ref }}
|
||||
|
||||
- name: Check Branch to Publish
|
||||
env:
|
||||
@@ -172,43 +176,61 @@ jobs:
|
||||
echo "is_publish_branch=false" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
########## ACRs ##########
|
||||
- name: Login to Prod Azure
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
- name: Add Git metadata to build version
|
||||
working-directory: apps/web
|
||||
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
|
||||
mv package.json.tmp package.json
|
||||
|
||||
########## Set up Docker ##########
|
||||
- name: Set up Docker
|
||||
uses: docker/setup-docker-action@b60f85385d03ac8acfca6d9996982511d8620a19 # v4.3.0
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
|
||||
daemon-config: |
|
||||
{
|
||||
"debug": true,
|
||||
"features": {
|
||||
"containerd-snapshotter": true
|
||||
}
|
||||
}
|
||||
|
||||
- name: Set up QEMU emulators
|
||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
|
||||
|
||||
########## ACRs ##########
|
||||
- name: Log in to Azure
|
||||
if: ${{ needs.setup.outputs.has_secrets == 'true' }}
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Log into Prod container registry
|
||||
run: az acr login -n bitwardenprod
|
||||
|
||||
- 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: Download ${{ matrix.artifact_name }} artifact
|
||||
uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
|
||||
with:
|
||||
name: web-${{ env._VERSION }}-${{ matrix.artifact_name }}.zip
|
||||
path: apps/web
|
||||
if: ${{ needs.setup.outputs.has_secrets == 'true' }}
|
||||
run: az acr login -n ${_AZ_REGISTRY%.azurecr.io}
|
||||
|
||||
########## Generate image tag and build Docker image ##########
|
||||
- name: Generate Docker image tag
|
||||
- name: Generate container image tag
|
||||
id: tag
|
||||
run: |
|
||||
if [[ $(grep "pull" <<< "${GITHUB_REF}") ]]; then
|
||||
IMAGE_TAG=$(echo "${GITHUB_HEAD_REF}" | sed "s#/#-#g")
|
||||
if [[ "${GITHUB_EVENT_NAME}" == "pull_request" || "${GITHUB_EVENT_NAME}" == "pull_request_target" ]]; then
|
||||
IMAGE_TAG=$(echo "${GITHUB_HEAD_REF}" | sed "s/[^a-zA-Z0-9]/-/g") # Sanitize branch name to alphanumeric only
|
||||
else
|
||||
IMAGE_TAG=$(echo "${GITHUB_REF_NAME}" | sed "s#/#-#g")
|
||||
fi
|
||||
|
||||
if [[ "${{ github.event.pull_request.head.repo.fork }}" == "true" ]]; then
|
||||
SANITIZED_REPO_NAME=$(echo "$_GITHUB_PR_REPO_NAME" | sed "s/[^a-zA-Z0-9]/-/g") # Sanitize repo name to alphanumeric only
|
||||
IMAGE_TAG=$SANITIZED_REPO_NAME-$IMAGE_TAG # Add repo name to the tag
|
||||
IMAGE_TAG=${IMAGE_TAG:0:128} # Limit to 128 characters, as that's the max length for Docker image tags
|
||||
fi
|
||||
|
||||
if [[ "$IMAGE_TAG" == "main" ]]; then
|
||||
IMAGE_TAG=dev
|
||||
fi
|
||||
@@ -222,10 +244,6 @@ jobs:
|
||||
echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT
|
||||
|
||||
########## Build Image ##########
|
||||
- name: Extract artifact
|
||||
working-directory: apps/web
|
||||
run: unzip web-${{ env._VERSION }}-${{ matrix.artifact_name }}.zip
|
||||
|
||||
- name: Generate image full name
|
||||
id: image-name
|
||||
env:
|
||||
@@ -234,33 +252,109 @@ jobs:
|
||||
run: echo "name=$_AZ_REGISTRY/${PROJECT_NAME}:${IMAGE_TAG}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Build Docker image
|
||||
uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0
|
||||
id: build-container
|
||||
uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d # v6.12.0
|
||||
with:
|
||||
context: apps/web
|
||||
build-args: |
|
||||
NODE_VERSION=${{ env._NODE_VERSION }}
|
||||
NPM_COMMAND=${{ matrix.npm_command }}
|
||||
context: .
|
||||
file: apps/web/Dockerfile
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
load: true
|
||||
platforms: |
|
||||
linux/amd64,
|
||||
linux/arm/v7,
|
||||
linux/arm64
|
||||
push: false
|
||||
tags: ${{ steps.image-name.outputs.name }}
|
||||
secrets: |
|
||||
"GH_PAT=${{ steps.retrieve-secret-pat.outputs.github-pat-bitwarden-devops-bot-repo-scope }}"
|
||||
|
||||
- name: Push images
|
||||
if: ${{ needs.setup.outputs.has_secrets == 'true' }}
|
||||
env:
|
||||
IMAGE_NAME: ${{ steps.image-name.outputs.name }}
|
||||
run: docker push $IMAGE_NAME
|
||||
|
||||
- name: Zip project
|
||||
working-directory: apps/web
|
||||
env:
|
||||
IMAGE_NAME: ${{ steps.image-name.outputs.name }}
|
||||
run: |
|
||||
mkdir build
|
||||
docker run --rm --volume $(pwd)/build:/temp --entrypoint bash \
|
||||
$IMAGE_NAME -c "cp -r ./ /temp"
|
||||
|
||||
zip -r web-${{ env._VERSION }}-${{ matrix.artifact_name }}.zip build
|
||||
|
||||
- name: Upload ${{ matrix.artifact_name }} artifact
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
with:
|
||||
name: web-${{ env._VERSION }}-${{ matrix.artifact_name }}.zip
|
||||
path: apps/web/web-${{ env._VERSION }}-${{ matrix.artifact_name }}.zip
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Install Cosign
|
||||
if: github.event_name != 'pull_request_target' && github.ref == 'refs/heads/main'
|
||||
uses: sigstore/cosign-installer@3454372f43399081ed03b604cb2d021dabca52bb # v3.8.2
|
||||
|
||||
- name: Sign image with Cosign
|
||||
if: github.event_name != 'pull_request_target' && github.ref == 'refs/heads/main'
|
||||
env:
|
||||
DIGEST: ${{ steps.build-container.outputs.digest }}
|
||||
TAGS: ${{ steps.image-name.outputs.name }}
|
||||
run: |
|
||||
IFS="," read -a tags <<< "${TAGS}"
|
||||
images=""
|
||||
for tag in "${tags[@]}"; do
|
||||
images+="${tag}@${DIGEST} "
|
||||
done
|
||||
cosign sign --yes ${images}
|
||||
|
||||
- name: Scan Docker image
|
||||
if: ${{ needs.setup.outputs.has_secrets == 'true' }}
|
||||
id: container-scan
|
||||
uses: anchore/scan-action@2c901ab7378897c01b8efaa2d0c9bf519cc64b9e # v6.2.0
|
||||
with:
|
||||
image: ${{ steps.image-name.outputs.name }}
|
||||
fail-build: false
|
||||
output-format: sarif
|
||||
|
||||
- name: Upload Grype results to GitHub
|
||||
if: ${{ needs.setup.outputs.has_secrets == 'true' }}
|
||||
uses: github/codeql-action/upload-sarif@d68b2d4edb4189fd2a5366ac14e72027bd4b37dd # v3.28.2
|
||||
with:
|
||||
sarif_file: ${{ steps.container-scan.outputs.sarif }}
|
||||
sha: ${{ contains(github.event_name, 'pull_request') && github.event.pull_request.head.sha || github.sha }}
|
||||
ref: ${{ contains(github.event_name, 'pull_request') && format('refs/pull/{0}/head', github.event.pull_request.number) || github.ref }}
|
||||
|
||||
- name: Log out of Docker
|
||||
run: docker logout
|
||||
run: docker logout $_AZ_REGISTRY
|
||||
|
||||
- name: Log out from Azure
|
||||
if: ${{ needs.setup.outputs.has_secrets == 'true' }}
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
|
||||
crowdin-push:
|
||||
name: Crowdin Push
|
||||
if: github.ref == 'refs/heads/main'
|
||||
needs: build-artifacts
|
||||
runs-on: ubuntu-22.04
|
||||
if: github.event_name != 'pull_request_target' && github.ref == 'refs/heads/main'
|
||||
needs: build-containers
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
id-token: write
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- name: Login to Azure
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
@@ -269,8 +363,11 @@ jobs:
|
||||
keyvault: "bitwarden-ci"
|
||||
secrets: "crowdin-api-token"
|
||||
|
||||
- name: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- name: Upload Sources
|
||||
uses: crowdin/github-action@c953b17499daa6be3e5afbf7a63616fb02d8b18d # v1.19.0
|
||||
uses: crowdin/github-action@f214c8723025f41fc55b2ad26e67b60b80b1885d # v2.7.1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
|
||||
@@ -281,16 +378,21 @@ jobs:
|
||||
upload_sources: true
|
||||
upload_translations: false
|
||||
|
||||
|
||||
trigger-web-vault-deploy:
|
||||
name: Trigger web vault deploy
|
||||
if: github.ref == 'refs/heads/main'
|
||||
runs-on: ubuntu-22.04
|
||||
needs: build-artifacts
|
||||
if: github.event_name != 'pull_request_target' && github.ref == 'refs/heads/main'
|
||||
runs-on: ubuntu-24.04
|
||||
needs: build-containers
|
||||
permissions:
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Login to Azure - CI Subscription
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
- name: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Retrieve github PAT secrets
|
||||
id: retrieve-secret-pat
|
||||
@@ -299,7 +401,10 @@ jobs:
|
||||
keyvault: "bitwarden-ci"
|
||||
secrets: "github-pat-bitwarden-devops-bot-repo-scope"
|
||||
|
||||
- name: Trigger web vault deploy
|
||||
- name: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- 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 }}
|
||||
@@ -311,30 +416,37 @@ jobs:
|
||||
ref: 'main',
|
||||
inputs: {
|
||||
'environment': 'USDEV',
|
||||
'branch-or-tag': 'main'
|
||||
'build-web-run-id': '${{ github.run_id }}'
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
check-failures:
|
||||
name: Check for failures
|
||||
if: always()
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
needs:
|
||||
- setup
|
||||
- build-artifacts
|
||||
- build-containers
|
||||
- crowdin-push
|
||||
- trigger-web-vault-deploy
|
||||
permissions:
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Check if any job failed
|
||||
if: (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc') && contains(needs.*.result, 'failure')
|
||||
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@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
- name: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
if: failure()
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
@@ -344,8 +456,11 @@ jobs:
|
||||
keyvault: "bitwarden-ci"
|
||||
secrets: "devops-alerts-slack-webhook-url"
|
||||
|
||||
- name: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- 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 }}
|
||||
|
||||
79
.github/workflows/chromatic.yml
vendored
79
.github/workflows/chromatic.yml
vendored
@@ -1,56 +1,107 @@
|
||||
---
|
||||
name: Chromatic
|
||||
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'renovate/**'
|
||||
paths-ignore:
|
||||
- '.github/workflows/**'
|
||||
branches:
|
||||
- "main"
|
||||
- "rc"
|
||||
- "hotfix-rc"
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened]
|
||||
branches:
|
||||
- "main"
|
||||
|
||||
jobs:
|
||||
check-run:
|
||||
name: Check PR run
|
||||
uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
chromatic:
|
||||
name: Chromatic
|
||||
runs-on: ubuntu-22.04
|
||||
needs: check-run
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get Node Version
|
||||
- name: Get changed files
|
||||
id: get-changed-files-for-chromatic
|
||||
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
|
||||
with:
|
||||
filters: |
|
||||
storyFiles:
|
||||
- "apps/!(cli)/**"
|
||||
- "bitwarden_license/bit-web/src/app/**"
|
||||
- "libs/!(eslint)/**"
|
||||
- "package.json"
|
||||
- ".storybook/**"
|
||||
|
||||
- name: Get Node version
|
||||
id: retrieve-node-version
|
||||
if: steps.get-changed-files-for-chromatic.outputs.storyFiles == 'true'
|
||||
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@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
||||
with:
|
||||
node-version: ${{ steps.retrieve-node-version.outputs.node_version }}
|
||||
if: steps.get-changed-files-for-chromatic.outputs.storyFiles == 'true'
|
||||
|
||||
- name: Cache npm
|
||||
- name: Cache NPM
|
||||
id: npm-cache
|
||||
uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1
|
||||
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
with:
|
||||
path: "~/.npm"
|
||||
key: ${{ runner.os }}-npm-chromatic-${{ hashFiles('**/package-lock.json') }}
|
||||
if: steps.get-changed-files-for-chromatic.outputs.storyFiles == 'true'
|
||||
|
||||
- name: Install Node dependencies
|
||||
if: steps.get-changed-files-for-chromatic.outputs.storyFiles == 'true'
|
||||
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
|
||||
if: steps.get-changed-files-for-chromatic.outputs.storyFiles == 'true'
|
||||
run: npm run build-storybook:ci
|
||||
|
||||
- name: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Get Azure Key Vault secrets
|
||||
id: get-kv-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: gh-clients
|
||||
secrets: "CHROMATIC-PROJECT-TOKEN"
|
||||
|
||||
- name: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- name: Publish to Chromatic
|
||||
uses: chromaui/action@c9067691aca4a28d6fbb40d9eea6e144369fbcae # v10.9.5
|
||||
uses: chromaui/action@e8cc4c31775280b175a3c440076c00d19a9014d7 # v11.28.2
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
||||
projectToken: ${{ steps.get-kv-secrets.outputs.CHROMATIC-PROJECT-TOKEN }}
|
||||
storybookBuildDir: ./storybook-static
|
||||
exitOnceUploaded: true
|
||||
onlyChanged: true
|
||||
externals: "[\"libs/components/**/*.scss\", \"libs/components/**/*.css\", \"libs/components/tailwind.config*.js\"]"
|
||||
# Rather than use an `if` check on the whole publish step, we need to tell Chromatic to skip so that any Chromatic-spawned actions are properly skipped
|
||||
skip: ${{ steps.get-changed-files-for-chromatic.outputs.storyFiles == 'false' }}
|
||||
|
||||
42
.github/workflows/crowdin-pull.yml
vendored
42
.github/workflows/crowdin-pull.yml
vendored
@@ -1,4 +1,3 @@
|
||||
---
|
||||
name: Crowdin Sync
|
||||
|
||||
on:
|
||||
@@ -10,7 +9,10 @@ on:
|
||||
jobs:
|
||||
crowdin-sync:
|
||||
name: Autosync
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -22,13 +24,19 @@ jobs:
|
||||
- app_name: web
|
||||
crowdin_project_id: "308189"
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- name: Login to Azure
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
- name: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Get Azure Key Vault secrets
|
||||
id: get-kv-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: gh-org-bitwarden
|
||||
secrets: "BW-GHAPP-ID,BW-GHAPP-KEY"
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
@@ -37,10 +45,25 @@ jobs:
|
||||
keyvault: "bitwarden-ci"
|
||||
secrets: "crowdin-api-token, github-gpg-private-key, github-gpg-private-key-passphrase"
|
||||
|
||||
- name: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- name: Generate GH App token
|
||||
uses: actions/create-github-app-token@30bf6253fa41bdc8d1501d202ad15287582246b4 # v2.0.3
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-ID }}
|
||||
private-key: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-KEY }}
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
token: ${{ steps.app-token.outputs.token }}
|
||||
|
||||
- name: Download translations
|
||||
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:
|
||||
@@ -59,4 +82,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 }}
|
||||
|
||||
|
||||
342
.github/workflows/deploy-web.yml
vendored
342
.github/workflows/deploy-web.yml
vendored
@@ -1,4 +1,3 @@
|
||||
---
|
||||
name: Deploy Web Vault
|
||||
run-name: Deploy Web Vault to ${{ inputs.environment }} from ${{ inputs.branch-or-tag }}
|
||||
|
||||
@@ -7,7 +6,7 @@ on:
|
||||
inputs:
|
||||
environment:
|
||||
description: 'Environment'
|
||||
default: 'QA'
|
||||
default: 'USQA'
|
||||
type: choice
|
||||
options:
|
||||
- USQA
|
||||
@@ -27,6 +26,10 @@ on:
|
||||
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:
|
||||
@@ -46,6 +49,10 @@ on:
|
||||
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
|
||||
@@ -56,13 +63,15 @@ jobs:
|
||||
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 }}
|
||||
environment_url: ${{ steps.config.outputs.environment_url }}
|
||||
environment_name: ${{ steps.config.outputs.environment_name }}
|
||||
environment_artifact: ${{ steps.config.outputs.environment_artifact }}
|
||||
azure_login_client_key_name: ${{ steps.config.outputs.azure_login_client_key_name }}
|
||||
azure_login_subscription_id_key_name: ${{ steps.config.outputs.azure_login_subscription_id_key_name }}
|
||||
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
|
||||
@@ -73,104 +82,134 @@ jobs:
|
||||
|
||||
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 "azure_login_client_key_name=AZURE_CLIENT_ID_USQA" >> $GITHUB_OUTPUT
|
||||
echo "azure_login_subscription_id_key_name=AZURE_SUBSCRIPTION_ID_USQA" >> $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 "azure_login_client_key_name=AZURE_CLIENT_ID_EUQA" >> $GITHUB_OUTPUT
|
||||
echo "azure_login_subscription_id_key_name=AZURE_SUBSCRIPTION_ID_EUQA" >> $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 "azure_login_client_key_name=AZURE_CLIENT_ID_USPROD" >> $GITHUB_OUTPUT
|
||||
echo "azure_login_subscription_id_key_name=AZURE_SUBSCRIPTION_ID_USPROD" >> $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 "azure_login_client_key_name=AZURE_CLIENT_ID_EUPROD" >> $GITHUB_OUTPUT
|
||||
echo "azure_login_subscription_id_key_name=AZURE_SUBSCRIPTION_ID_EUPROD" >> $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 "azure_login_client_key_name=AZURE_CLIENT_ID_USDEV" >> $GITHUB_OUTPUT
|
||||
echo "azure_login_subscription_id_key_name=AZURE_SUBSCRIPTION_ID_USDEV" >> $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
|
||||
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 }}
|
||||
name: Approval for Deployment to ${{ needs.setup.outputs.environment_name }}
|
||||
needs: setup
|
||||
runs-on: ubuntu-22.04
|
||||
environment: ${{ needs.setup.outputs.environment-name }}
|
||||
environment: ${{ needs.setup.outputs.environment_name }}
|
||||
steps:
|
||||
- name: Success Code
|
||||
run: exit 0
|
||||
|
||||
get-branch-or-tag-sha:
|
||||
name: Get Branch or Tag SHA
|
||||
runs-on: ubuntu-22.04
|
||||
outputs:
|
||||
branch-or-tag-sha: ${{ steps.get-branch-or-tag-sha.outputs.sha }}
|
||||
steps:
|
||||
- name: Checkout Branch
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
ref: ${{ inputs.branch-or-tag }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get Branch or Tag SHA
|
||||
id: get-branch-or-tag-sha
|
||||
run: |
|
||||
echo "sha=$(git rev-parse origin/${{ inputs.branch-or-tag }})" >> $GITHUB_OUTPUT
|
||||
|
||||
notify-start:
|
||||
name: Notify Slack with start message
|
||||
needs:
|
||||
- approval
|
||||
- setup
|
||||
- get-branch-or-tag-sha
|
||||
runs-on: ubuntu-22.04
|
||||
if: ${{ always() && contains( inputs.environment , 'QA' ) }}
|
||||
outputs:
|
||||
channel_id: ${{ steps.slack-message.outputs.channel_id }}
|
||||
ts: ${{ steps.slack-message.outputs.ts }}
|
||||
steps:
|
||||
- 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: team-eng-qa-devops
|
||||
event: 'start'
|
||||
commit-sha: ${{ needs.get-branch-or-tag-sha.outputs.branch-or-tag-sha }}
|
||||
url: https://github.com/bitwarden/clients/actions/runs/${{ github.run_id }}
|
||||
AZURE_KV_CI_SERVICE_PRINCIPAL: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
|
||||
artifact-check:
|
||||
name: Check if Web artifact is present
|
||||
runs-on: ubuntu-22.04
|
||||
needs: setup
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
env:
|
||||
_ENVIRONMENT_ARTIFACT: ${{ needs.setup.outputs.environment-artifact }}
|
||||
_ENVIRONMENT_ARTIFACT: ${{ needs.setup.outputs.environment_artifact }}
|
||||
outputs:
|
||||
artifact_build_commit: ${{ steps.set-artifact-commit.outputs.commit }}
|
||||
steps:
|
||||
- name: 'Download latest cloud asset from branch/tag: ${{ inputs.branch-or-tag }}'
|
||||
- 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-artifacts
|
||||
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
|
||||
@@ -179,23 +218,30 @@ jobs:
|
||||
branch: ${{ inputs.branch-or-tag }}
|
||||
artifacts: ${{ env._ENVIRONMENT_ARTIFACT }}
|
||||
|
||||
- name: Login to Azure
|
||||
if: ${{ steps.download-artifacts.outcome == 'failure' }}
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
- name: Log in to Azure
|
||||
if: ${{ steps.download-latest-artifacts.outcome == 'failure' }}
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Retrieve secrets for Build trigger
|
||||
if: ${{ steps.download-artifacts.outcome == 'failure' }}
|
||||
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: Log out from Azure
|
||||
if: ${{ steps.download-latest-artifacts.outcome == 'failure' }}
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- name: 'Trigger build web for missing branch/tag ${{ inputs.branch-or-tag }}'
|
||||
if: ${{ steps.download-artifacts.outcome == 'failure' }}
|
||||
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
|
||||
@@ -204,6 +250,65 @@ jobs:
|
||||
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' ) ) }}
|
||||
permissions:
|
||||
id-token: write
|
||||
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_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
|
||||
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
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:
|
||||
@@ -213,9 +318,12 @@ jobs:
|
||||
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 }}
|
||||
_ENVIRONMENT_URL: ${{ needs.setup.outputs.environment_url }}
|
||||
_ENVIRONMENT_NAME: ${{ needs.setup.outputs.environment_name }}
|
||||
_ENVIRONMENT_ARTIFACT: ${{ needs.setup.outputs.environment_artifact }}
|
||||
permissions:
|
||||
id-token: write
|
||||
deployments: write
|
||||
steps:
|
||||
- name: Create GitHub deployment
|
||||
uses: chrnorm/deployment-action@55729fcebec3d284f60f5bcabbd8376437d696b1 # v2.0.7
|
||||
@@ -227,29 +335,48 @@ jobs:
|
||||
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
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
creds: ${{ secrets[needs.setup.outputs.azure-login-creds] }}
|
||||
subscription_id: ${{ secrets[needs.setup.outputs.azure_login_subscription_id_key_name] }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets[needs.setup.outputs.azure_login_client_key_name] }}
|
||||
|
||||
- name: Retrieve Storage Account connection string for az sync
|
||||
if: ${{ needs.setup.outputs.sync-utility == '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 }}
|
||||
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' }}
|
||||
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 }}
|
||||
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: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- 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
|
||||
@@ -263,7 +390,7 @@ jobs:
|
||||
run: unzip ${{ env._ENVIRONMENT_ARTIFACT }}
|
||||
|
||||
- name: Sync to Azure Storage Account using az storage blob sync
|
||||
if: ${{ needs.setup.outputs.sync-utility == 'az-sync' }}
|
||||
if: ${{ needs.setup.outputs.sync_utility == 'az-sync' }}
|
||||
working-directory: apps/web
|
||||
run: |
|
||||
az storage blob sync \
|
||||
@@ -273,7 +400,7 @@ jobs:
|
||||
--delete-destination=${{ inputs.force-delete-destination }}
|
||||
|
||||
- name: Sync to Azure Storage Account using azcopy
|
||||
if: ${{ needs.setup.outputs.sync-utility == 'azcopy' }}
|
||||
if: ${{ needs.setup.outputs.sync_utility == 'azcopy' }}
|
||||
working-directory: apps/web
|
||||
env:
|
||||
AZCOPY_AUTO_LOGIN_TYPE: SPN
|
||||
@@ -313,21 +440,26 @@ jobs:
|
||||
notify:
|
||||
name: Notify Slack with result
|
||||
runs-on: ubuntu-22.04
|
||||
if: ${{ always() && contains( inputs.environment , 'QA' ) }}
|
||||
if: ${{ always() && ( contains( inputs.environment , 'QA' ) || contains( inputs.environment , 'DEV' ) ) }}
|
||||
needs:
|
||||
- setup
|
||||
- notify-start
|
||||
- azure-deploy
|
||||
- setup
|
||||
- get-branch-or-tag-sha
|
||||
- artifact-check
|
||||
permissions:
|
||||
id-token: write
|
||||
steps:
|
||||
- uses: bitwarden/gh-actions/report-deployment-status-to-slack@main
|
||||
- name: Notify Slack with result
|
||||
uses: bitwarden/gh-actions/report-deployment-status-to-slack@main
|
||||
with:
|
||||
project: Clients
|
||||
environment: ${{ needs.setup.outputs.environment-name }}
|
||||
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.get-branch-or-tag-sha.outputs.branch-or-tag-sha }}
|
||||
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 }}
|
||||
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
|
||||
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
4
.github/workflows/enforce-labels.yml
vendored
4
.github/workflows/enforce-labels.yml
vendored
@@ -1,10 +1,12 @@
|
||||
---
|
||||
name: Enforce PR labels
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
pull_request:
|
||||
types: [labeled, unlabeled, opened, edited, synchronize]
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
jobs:
|
||||
enforce-label:
|
||||
name: EnforceLabel
|
||||
|
||||
24
.github/workflows/label-issue-pull-request.yml
vendored
24
.github/workflows/label-issue-pull-request.yml
vendored
@@ -1,24 +0,0 @@
|
||||
# Runs creation of Pull Requests
|
||||
# If the PR destination branch is main, add a needs-qa label unless created by renovate[bot]
|
||||
---
|
||||
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:
|
||||
- 'main' # We only want to check when PRs target main
|
||||
|
||||
jobs:
|
||||
add-needs-qa-label:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.actor != 'renovate[bot]' }}
|
||||
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"
|
||||
55
.github/workflows/lint-crowdin-config.yml
vendored
Normal file
55
.github/workflows/lint-crowdin-config.yml
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
name: Lint Crowdin Config
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
paths:
|
||||
- '**/crowdin.yml'
|
||||
|
||||
jobs:
|
||||
lint-crowdin-config:
|
||||
name: Lint Crowdin Config ${{ matrix.app.name }}
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
strategy:
|
||||
matrix:
|
||||
app: [
|
||||
{ name: 'web', project_id: '308189', config_path: 'apps/web/crowdin.yml' },
|
||||
{ name: 'desktop', project_id: '299360', config_path: 'apps/desktop/crowdin.yml' },
|
||||
{ name: 'browser', project_id: '268134', config_path: 'apps/browser/crowdin.yml' }
|
||||
]
|
||||
steps:
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: "bitwarden-ci"
|
||||
secrets: "crowdin-api-token"
|
||||
|
||||
- name: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- name: Lint ${{ matrix.app.name }} config
|
||||
uses: crowdin/github-action@f214c8723025f41fc55b2ad26e67b60b80b1885d # v2.7.1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CROWDIN_PROJECT_ID: ${{ matrix.app.project_id }}
|
||||
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
|
||||
with:
|
||||
dryrun_action: true
|
||||
command: 'config lint'
|
||||
command_args: '--verbose -c ${{ matrix.app.config_path }}'
|
||||
60
.github/workflows/lint.yml
vendored
60
.github/workflows/lint.yml
vendored
@@ -1,13 +1,20 @@
|
||||
---
|
||||
name: Lint
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
branches-ignore:
|
||||
- 'l10n_master'
|
||||
- 'cf-pages'
|
||||
paths-ignore:
|
||||
- '.github/workflows/**'
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'rc'
|
||||
- 'hotfix-rc-*'
|
||||
paths-ignore:
|
||||
- '.github/workflows/**'
|
||||
workflow_dispatch:
|
||||
inputs: {}
|
||||
|
||||
@@ -15,13 +22,16 @@ defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Lint filenames (no capital characters)
|
||||
run: |
|
||||
@@ -35,6 +45,10 @@ jobs:
|
||||
! -path "*/.DS_Store" \
|
||||
! -path "*/*locales/*" \
|
||||
! -path "./.github/*" \
|
||||
! -path "*/README.md" \
|
||||
! -path "*/Cargo.toml" \
|
||||
! -path "*/Cargo.lock" \
|
||||
! -path "./apps/desktop/macos/*" \
|
||||
> tmp.txt
|
||||
diff <(sort .github/whitelist-capital-letters.txt) <(sort tmp.txt)
|
||||
|
||||
@@ -46,13 +60,45 @@ jobs:
|
||||
echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
||||
with:
|
||||
cache: 'npm'
|
||||
cache-dependency-path: '**/package-lock.json'
|
||||
node-version: ${{ steps.retrieve-node-version.outputs.node_version }}
|
||||
|
||||
- name: Install Node dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Lint unowned dependencies
|
||||
run: npm run lint:dep-ownership
|
||||
|
||||
- name: Run linter
|
||||
run: |
|
||||
npm ci
|
||||
npm run lint
|
||||
run: npm run lint
|
||||
|
||||
rust:
|
||||
name: Run Rust lint on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os || 'ubuntu-24.04' }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-24.04
|
||||
- macos-14
|
||||
- windows-2022
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Check Rust version
|
||||
run: rustup --version
|
||||
|
||||
- name: Run cargo fmt
|
||||
working-directory: ./apps/desktop/desktop_native
|
||||
run: cargo fmt --check
|
||||
|
||||
- name: Run Clippy
|
||||
working-directory: ./apps/desktop/desktop_native
|
||||
run: cargo clippy --all-features --tests
|
||||
env:
|
||||
RUSTFLAGS: "-D warnings"
|
||||
|
||||
36
.github/workflows/locales-lint.yml
vendored
Normal file
36
.github/workflows/locales-lint.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
name: Locales lint for Crowdin
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches-ignore:
|
||||
- 'l10n_master'
|
||||
- 'cf-pages'
|
||||
paths:
|
||||
- '**/messages.json'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
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
|
||||
268
.github/workflows/publish-cli.yml
vendored
Normal file
268
.github/workflows/publish-cli.yml
vendored
Normal file
@@ -0,0 +1,268 @@
|
||||
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: .
|
||||
permissions:
|
||||
contents: read
|
||||
deployments: write
|
||||
|
||||
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
|
||||
permissions:
|
||||
contents: read
|
||||
packages: read
|
||||
id-token: write
|
||||
if: inputs.snap_publish
|
||||
env:
|
||||
_PKG_VERSION: ${{ needs.setup.outputs.release_version }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: "bitwarden-ci"
|
||||
secrets: "snapcraft-store-token"
|
||||
|
||||
- name: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- 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
|
||||
permissions:
|
||||
contents: read
|
||||
packages: read
|
||||
id-token: write
|
||||
if: inputs.choco_publish
|
||||
env:
|
||||
_PKG_VERSION: ${{ needs.setup.outputs.release_version }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: "bitwarden-ci"
|
||||
secrets: "cli-choco-api-key"
|
||||
|
||||
- name: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- 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
|
||||
permissions:
|
||||
contents: read
|
||||
packages: read
|
||||
id-token: write
|
||||
if: inputs.npm_publish
|
||||
env:
|
||||
_PKG_VERSION: ${{ needs.setup.outputs.release_version }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: "bitwarden-ci"
|
||||
secrets: "npm-api-key"
|
||||
|
||||
- name: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- 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
|
||||
permissions:
|
||||
contents: read
|
||||
deployments: write
|
||||
|
||||
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 }}
|
||||
326
.github/workflows/publish-desktop.yml
vendored
Normal file
326
.github/workflows/publish-desktop.yml
vendored
Normal file
@@ -0,0 +1,326 @@
|
||||
name: Publish Desktop
|
||||
run-name: Publish Desktop ${{ inputs.publish_type }}
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
publish_type:
|
||||
description: 'Publish Options'
|
||||
required: true
|
||||
default: 'Publish'
|
||||
type: choice
|
||||
options:
|
||||
- Publish
|
||||
- Dry Run
|
||||
version:
|
||||
description: 'Version to publish (default: latest desktop release)'
|
||||
required: true
|
||||
type: string
|
||||
default: latest
|
||||
electron_rollout_percentage:
|
||||
description: 'Staged Rollout Percentage for Electron'
|
||||
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 }}
|
||||
permissions:
|
||||
contents: read
|
||||
deployments: write
|
||||
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
|
||||
permissions:
|
||||
contents: read
|
||||
packages: read
|
||||
id-token: write
|
||||
deployments: write
|
||||
env:
|
||||
_PKG_VERSION: ${{ needs.setup.outputs.release_version }}
|
||||
_RELEASE_TAG: ${{ needs.setup.outputs.tag_name }}
|
||||
steps:
|
||||
- name: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: 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: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- 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.electron_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
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
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: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: "bitwarden-ci"
|
||||
secrets: "snapcraft-store-token"
|
||||
|
||||
- name: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- 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
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
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: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: "bitwarden-ci"
|
||||
secrets: "cli-choco-api-key"
|
||||
|
||||
- name: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- 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
|
||||
permissions:
|
||||
contents: read
|
||||
deployments: write
|
||||
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 }}
|
||||
194
.github/workflows/publish-web.yml
vendored
Normal file
194
.github/workflows/publish-web.yml
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
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 }}
|
||||
permissions:
|
||||
contents: read
|
||||
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
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read
|
||||
deployments: write
|
||||
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: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Login to Azure ACR
|
||||
run: az acr login -n bitwardenprod
|
||||
|
||||
- name: 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: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- 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
|
||||
|
||||
self-host-unified-build:
|
||||
name: Trigger self-host unified build
|
||||
runs-on: ubuntu-22.04
|
||||
needs:
|
||||
- setup
|
||||
permissions:
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: 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: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- name: Trigger self-host build
|
||||
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: 'self-host',
|
||||
workflow_id: 'build-unified.yml',
|
||||
ref: 'main',
|
||||
inputs: {
|
||||
use_latest_core_version: true
|
||||
}
|
||||
});
|
||||
57
.github/workflows/release-browser.yml
vendored
57
.github/workflows/release-browser.yml
vendored
@@ -1,4 +1,3 @@
|
||||
---
|
||||
name: Release Browser
|
||||
run-name: Release Browser ${{ inputs.release_type }}
|
||||
|
||||
@@ -23,11 +22,13 @@ jobs:
|
||||
setup:
|
||||
name: Setup
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
release-version: ${{ steps.version.outputs.version }}
|
||||
release_version: ${{ steps.version.outputs.version }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Branch check
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
@@ -54,9 +55,11 @@ jobs:
|
||||
name: Locales Test
|
||||
runs-on: ubuntu-22.04
|
||||
needs: setup
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Testing locales - extName length
|
||||
run: |
|
||||
@@ -90,17 +93,9 @@ jobs:
|
||||
needs:
|
||||
- setup
|
||||
- locales-test
|
||||
permissions:
|
||||
contents: write
|
||||
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: '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@main
|
||||
@@ -129,7 +124,7 @@ jobs:
|
||||
|
||||
- name: Rename build artifacts
|
||||
env:
|
||||
PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||
PACKAGE_VERSION: ${{ needs.setup.outputs.release_version }}
|
||||
run: |
|
||||
mv browser-source.zip browser-source-$PACKAGE_VERSION.zip
|
||||
mv dist-chrome.zip dist-chrome-$PACKAGE_VERSION.zip
|
||||
@@ -139,32 +134,16 @@ jobs:
|
||||
|
||||
- name: Create release
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.0
|
||||
uses: ncipollo/release-action@cdcc88a9acf3ca41c16c37bb7d21b9ad48560d87 # v1.15.0
|
||||
with:
|
||||
artifacts: 'browser-source-${{ needs.setup.outputs.release-version }}.zip,
|
||||
dist-chrome-${{ needs.setup.outputs.release-version }}.zip,
|
||||
dist-opera-${{ needs.setup.outputs.release-version }}.zip,
|
||||
dist-firefox-${{ needs.setup.outputs.release-version }}.zip,
|
||||
dist-edge-${{ needs.setup.outputs.release-version }}.zip'
|
||||
artifacts: 'browser-source-${{ needs.setup.outputs.release_version }}.zip,
|
||||
dist-chrome-${{ needs.setup.outputs.release_version }}.zip,
|
||||
dist-opera-${{ needs.setup.outputs.release_version }}.zip,
|
||||
dist-firefox-${{ needs.setup.outputs.release_version }}.zip,
|
||||
dist-edge-${{ needs.setup.outputs.release_version }}.zip'
|
||||
commit: ${{ github.sha }}
|
||||
tag: "browser-v${{ needs.setup.outputs.release-version }}"
|
||||
name: "Browser v${{ needs.setup.outputs.release-version }}"
|
||||
tag: "browser-v${{ needs.setup.outputs.release_version }}"
|
||||
name: "Browser v${{ needs.setup.outputs.release_version }}"
|
||||
body: "<insert release notes here>"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
draft: true
|
||||
|
||||
- name: Update deployment status to Success
|
||||
if: ${{ success() }}
|
||||
uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3
|
||||
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@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
state: 'failure'
|
||||
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
|
||||
|
||||
254
.github/workflows/release-cli.yml
vendored
254
.github/workflows/release-cli.yml
vendored
@@ -1,4 +1,3 @@
|
||||
---
|
||||
name: Release CLI
|
||||
run-name: Release CLI ${{ inputs.release_type }}
|
||||
|
||||
@@ -14,39 +13,26 @@ 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:
|
||||
working-directory: apps/cli
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
name: Setup
|
||||
runs-on: ubuntu-22.04
|
||||
outputs:
|
||||
release-version: ${{ steps.version.outputs.version }}
|
||||
release_version: ${{ steps.version.outputs.version }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
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 "==================================="
|
||||
@@ -59,25 +45,21 @@ jobs:
|
||||
id: version
|
||||
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@55729fcebec3d284f60f5bcabbd8376437d696b1 # v2.0.7
|
||||
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
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Download all Release artifacts
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
if: ${{ inputs.release_type != 'Dry Run' }}
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
with:
|
||||
workflow: build-cli.yml
|
||||
@@ -86,7 +68,7 @@ jobs:
|
||||
branch: ${{ github.ref_name }}
|
||||
|
||||
- name: Dry Run - Download all artifacts
|
||||
if: ${{ github.event.inputs.release_type == 'Dry Run' }}
|
||||
if: ${{ inputs.release_type == 'Dry Run' }}
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
with:
|
||||
workflow: build-cli.yml
|
||||
@@ -95,209 +77,25 @@ jobs:
|
||||
branch: main
|
||||
|
||||
- name: Create release
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.0
|
||||
if: ${{ inputs.release_type != 'Dry Run' }}
|
||||
uses: ncipollo/release-action@cdcc88a9acf3ca41c16c37bb7d21b9ad48560d87 # v1.15.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,
|
||||
apps/cli/bw-windows-sha256-${{ env.PKG_VERSION }}.txt,
|
||||
artifacts: "apps/cli/bw-oss-windows-${{ env.PKG_VERSION }}.zip,
|
||||
apps/cli/bw-windows-${{ env.PKG_VERSION }}.zip,
|
||||
apps/cli/bw-oss-macos-${{ env.PKG_VERSION }}.zip,
|
||||
apps/cli/bw-oss-macos-arm64-${{ env.PKG_VERSION }}.zip,
|
||||
apps/cli/bw-macos-${{ env.PKG_VERSION }}.zip,
|
||||
apps/cli/bw-macos-sha256-${{ env.PKG_VERSION }}.txt,
|
||||
apps/cli/bw-macos-arm64-${{ env.PKG_VERSION }}.zip,
|
||||
apps/cli/bw-oss-linux-${{ env.PKG_VERSION }}.zip,
|
||||
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/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@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3
|
||||
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@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3
|
||||
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: inputs.snap_publish
|
||||
env:
|
||||
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- 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
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
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@main
|
||||
with:
|
||||
workflow: build-cli.yml
|
||||
path: apps/cli
|
||||
workflow_conclusion: success
|
||||
branch: main
|
||||
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 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@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- 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
|
||||
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@main
|
||||
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@main
|
||||
with:
|
||||
workflow: build-cli.yml
|
||||
path: apps/cli/dist
|
||||
workflow_conclusion: success
|
||||
branch: main
|
||||
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-22.04
|
||||
needs: setup
|
||||
if: inputs.npm_publish
|
||||
env:
|
||||
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- 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 artifacts
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
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@main
|
||||
with:
|
||||
workflow: build-cli.yml
|
||||
path: apps/cli/build
|
||||
workflow_conclusion: success
|
||||
branch: main
|
||||
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
|
||||
|
||||
296
.github/workflows/release-desktop-beta.yml
vendored
296
.github/workflows/release-desktop-beta.yml
vendored
@@ -1,4 +1,3 @@
|
||||
---
|
||||
name: Release Desktop Beta
|
||||
|
||||
on:
|
||||
@@ -16,15 +15,17 @@ jobs:
|
||||
setup:
|
||||
name: Setup
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
contents: write
|
||||
outputs:
|
||||
release-version: ${{ steps.version.outputs.version }}
|
||||
release-channel: ${{ steps.release-channel.outputs.channel }}
|
||||
branch-name: ${{ steps.branch.outputs.branch-name }}
|
||||
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@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Branch check
|
||||
run: |
|
||||
@@ -64,7 +65,7 @@ jobs:
|
||||
echo "build_number=$BUILD_NUMBER" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Get Version Channel
|
||||
id: release-channel
|
||||
id: release_channel
|
||||
run: |
|
||||
case "${{ steps.version.outputs.version }}" in
|
||||
*"alpha"*)
|
||||
@@ -103,7 +104,7 @@ jobs:
|
||||
|
||||
git push -u origin $branch_name
|
||||
|
||||
echo "branch-name=$branch_name" >> $GITHUB_OUTPUT
|
||||
echo "branch_name=$branch_name" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Get Node Version
|
||||
id: retrieve-node-version
|
||||
@@ -116,8 +117,10 @@ jobs:
|
||||
name: Linux Build
|
||||
runs-on: ubuntu-22.04
|
||||
needs: setup
|
||||
permissions:
|
||||
contents: read
|
||||
env:
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.release_version }}
|
||||
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
|
||||
NODE_OPTIONS: --max_old_space_size=4096
|
||||
defaults:
|
||||
@@ -125,12 +128,12 @@ jobs:
|
||||
working-directory: apps/desktop
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
ref: ${{ needs.setup.outputs.branch-name }}
|
||||
ref: ${{ needs.setup.outputs.branch_name }}
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
||||
with:
|
||||
cache: 'npm'
|
||||
cache-dependency-path: '**/package-lock.json'
|
||||
@@ -139,7 +142,7 @@ jobs:
|
||||
- name: Set up environment
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install pkg-config libxss-dev libsecret-1-dev rpm
|
||||
sudo apt-get -y install pkg-config libxss-dev rpm
|
||||
|
||||
- name: Set up Snap
|
||||
run: sudo snap install snapcraft --classic
|
||||
@@ -159,45 +162,45 @@ jobs:
|
||||
run: npm run dist:lin
|
||||
|
||||
- name: Upload .deb artifact
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
with:
|
||||
name: ${{ needs.setup.outputs.release-channel }}-linux.yml
|
||||
path: apps/desktop/dist/${{ needs.setup.outputs.release-channel }}-linux.yml
|
||||
name: ${{ needs.setup.outputs.release_channel }}-linux.yml
|
||||
path: apps/desktop/dist/${{ needs.setup.outputs.release_channel }}-linux.yml
|
||||
if-no-files-found: error
|
||||
|
||||
|
||||
@@ -205,22 +208,25 @@ jobs:
|
||||
name: Windows Build
|
||||
runs-on: windows-2022
|
||||
needs: setup
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
defaults:
|
||||
run:
|
||||
shell: pwsh
|
||||
working-directory: apps/desktop
|
||||
env:
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||
_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@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
ref: ${{ needs.setup.outputs.branch-name }}
|
||||
ref: ${{ needs.setup.outputs.branch_name }}
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
||||
with:
|
||||
cache: 'npm'
|
||||
cache-dependency-path: '**/package-lock.json'
|
||||
@@ -238,10 +244,12 @@ jobs:
|
||||
npm --version
|
||||
choco --version
|
||||
|
||||
- name: Login to Azure
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
- name: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
@@ -254,6 +262,9 @@ jobs:
|
||||
code-signing-client-secret,
|
||||
code-signing-cert-name"
|
||||
|
||||
- name: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- name: Install Node dependencies
|
||||
run: npm ci
|
||||
working-directory: ./
|
||||
@@ -300,94 +311,94 @@ jobs:
|
||||
-NewName bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z
|
||||
|
||||
- name: Upload portable exe artifact
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
with:
|
||||
name: ${{ needs.setup.outputs.release-channel }}.yml
|
||||
path: apps/desktop/dist/nsis-web/${{ needs.setup.outputs.release-channel }}.yml
|
||||
name: ${{ needs.setup.outputs.release_channel }}.yml
|
||||
path: apps/desktop/dist/nsis-web/${{ needs.setup.outputs.release_channel }}.yml
|
||||
if-no-files-found: error
|
||||
|
||||
|
||||
@@ -395,8 +406,11 @@ jobs:
|
||||
name: MacOS Build
|
||||
runs-on: macos-13
|
||||
needs: setup
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
env:
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.release_version }}
|
||||
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
|
||||
NODE_OPTIONS: --max_old_space_size=4096
|
||||
defaults:
|
||||
@@ -404,17 +418,20 @@ jobs:
|
||||
working-directory: apps/desktop
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
ref: ${{ needs.setup.outputs.branch-name }}
|
||||
ref: ${{ needs.setup.outputs.branch_name }}
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
||||
with:
|
||||
cache: 'npm'
|
||||
cache-dependency-path: '**/package-lock.json'
|
||||
node-version: ${{ env._NODE_VERSION }}
|
||||
|
||||
- name: Set up Node-gyp
|
||||
run: python3 -m pip install setuptools
|
||||
|
||||
- name: Print environment
|
||||
run: |
|
||||
node --version
|
||||
@@ -424,18 +441,32 @@ jobs:
|
||||
|
||||
- name: Cache Build
|
||||
id: build-cache
|
||||
uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1
|
||||
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
with:
|
||||
path: apps/desktop/build
|
||||
key: ${{ runner.os }}-${{ github.run_id }}-build
|
||||
|
||||
- name: Cache Safari
|
||||
id: safari-cache
|
||||
uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1
|
||||
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
with:
|
||||
path: apps/browser/dist/Safari
|
||||
key: ${{ runner.os }}-${{ github.run_id }}-safari-extension
|
||||
|
||||
- name: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Get Azure Key Vault secrets
|
||||
id: get-kv-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: gh-clients
|
||||
secrets: "KEYCHAIN-PASSWORD"
|
||||
|
||||
- name: Download Provisioning Profiles secrets
|
||||
env:
|
||||
ACCOUNT_NAME: bitwardenci
|
||||
@@ -454,7 +485,7 @@ jobs:
|
||||
|
||||
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
|
||||
|
||||
@@ -470,9 +501,12 @@ jobs:
|
||||
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: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- name: Set up keychain
|
||||
env:
|
||||
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
|
||||
KEYCHAIN_PASSWORD: ${{ steps.get-kv-secrets.outputs.KEYCHAIN-PASSWORD }}
|
||||
run: |
|
||||
security create-keychain -p $KEYCHAIN_PASSWORD build.keychain
|
||||
security default-keychain -s build.keychain
|
||||
@@ -526,8 +560,12 @@ jobs:
|
||||
needs:
|
||||
- setup
|
||||
- macos-build
|
||||
permissions:
|
||||
contents: read
|
||||
packages: read
|
||||
id-token: write
|
||||
env:
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.release_version }}
|
||||
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
|
||||
NODE_OPTIONS: --max_old_space_size=4096
|
||||
defaults:
|
||||
@@ -535,17 +573,20 @@ jobs:
|
||||
working-directory: apps/desktop
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
ref: ${{ needs.setup.outputs.branch-name }}
|
||||
ref: ${{ needs.setup.outputs.branch_name }}
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
||||
with:
|
||||
cache: 'npm'
|
||||
cache-dependency-path: '**/package-lock.json'
|
||||
node-version: ${{ env._NODE_VERSION }}
|
||||
|
||||
- name: Set up Node-gyp
|
||||
run: python3 -m pip install setuptools
|
||||
|
||||
- name: Print environment
|
||||
run: |
|
||||
node --version
|
||||
@@ -555,22 +596,31 @@ jobs:
|
||||
|
||||
- name: Get Build Cache
|
||||
id: build-cache
|
||||
uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1
|
||||
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
with:
|
||||
path: apps/desktop/build
|
||||
key: ${{ runner.os }}-${{ github.run_id }}-build
|
||||
|
||||
- name: Setup Safari Cache
|
||||
id: safari-cache
|
||||
uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1
|
||||
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
with:
|
||||
path: apps/browser/dist/Safari
|
||||
key: ${{ runner.os }}-${{ github.run_id }}-safari-extension
|
||||
|
||||
- name: Login to Azure
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
- name: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Get Azure Key Vault secrets
|
||||
id: get-kv-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: gh-clients
|
||||
secrets: "KEYCHAIN-PASSWORD,APPLE-ID-USERNAME,APPLE-ID-PASSWORD"
|
||||
|
||||
- name: Download Provisioning Profiles secrets
|
||||
env:
|
||||
@@ -590,7 +640,7 @@ jobs:
|
||||
|
||||
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
|
||||
|
||||
@@ -606,9 +656,12 @@ jobs:
|
||||
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: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- name: Set up keychain
|
||||
env:
|
||||
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
|
||||
KEYCHAIN_PASSWORD: ${{ steps.get-kv-secrets.outputs.KEYCHAIN-PASSWORD }}
|
||||
run: |
|
||||
security create-keychain -p $KEYCHAIN_PASSWORD build.keychain
|
||||
security default-keychain -s build.keychain
|
||||
@@ -659,7 +712,7 @@ jobs:
|
||||
|
||||
- name: Download artifact from hotfix-rc
|
||||
if: github.ref == 'refs/heads/hotfix-rc'
|
||||
uses: dawidd6/action-download-artifact@71072fbb1229e1317f1a8de6b04206afb461bd67 # v3.1.2
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
with:
|
||||
workflow: build-browser.yml
|
||||
workflow_conclusion: success
|
||||
@@ -668,7 +721,7 @@ jobs:
|
||||
|
||||
- name: Download artifact from rc
|
||||
if: github.ref == 'refs/heads/rc'
|
||||
uses: dawidd6/action-download-artifact@71072fbb1229e1317f1a8de6b04206afb461bd67 # v3.1.2
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
with:
|
||||
workflow: build-browser.yml
|
||||
workflow_conclusion: success
|
||||
@@ -677,7 +730,7 @@ jobs:
|
||||
|
||||
- name: Download artifacts from main
|
||||
if: ${{ github.ref != 'refs/heads/rc' && github.ref != 'refs/heads/hotfix-rc' }}
|
||||
uses: dawidd6/action-download-artifact@71072fbb1229e1317f1a8de6b04206afb461bd67 # v3.1.2
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
with:
|
||||
workflow: build-browser.yml
|
||||
workflow_conclusion: success
|
||||
@@ -697,36 +750,36 @@ jobs:
|
||||
|
||||
- name: Build application (dist)
|
||||
env:
|
||||
APPLE_ID_USERNAME: ${{ secrets.APPLE_ID_USERNAME }}
|
||||
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||||
APPLE_ID_USERNAME: ${{ steps.get-kv-secrets.outputs.APPLE-ID-USERNAME }}
|
||||
APPLE_ID_PASSWORD: ${{ steps.get-kv-secrets.outputs.APPLE-ID-PASSWORD }}
|
||||
run: npm run pack:mac
|
||||
|
||||
- name: Upload .zip artifact
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
with:
|
||||
name: ${{ needs.setup.outputs.release-channel }}-mac.yml
|
||||
path: apps/desktop/dist/${{ needs.setup.outputs.release-channel }}-mac.yml
|
||||
name: ${{ needs.setup.outputs.release_channel }}-mac.yml
|
||||
path: apps/desktop/dist/${{ needs.setup.outputs.release_channel }}-mac.yml
|
||||
if-no-files-found: error
|
||||
|
||||
|
||||
@@ -736,8 +789,12 @@ jobs:
|
||||
needs:
|
||||
- setup
|
||||
- macos-build
|
||||
permissions:
|
||||
contents: read
|
||||
packages: read
|
||||
id-token: write
|
||||
env:
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.release_version }}
|
||||
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
|
||||
NODE_OPTIONS: --max_old_space_size=4096
|
||||
defaults:
|
||||
@@ -745,17 +802,20 @@ jobs:
|
||||
working-directory: apps/desktop
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
ref: ${{ needs.setup.outputs.branch-name }}
|
||||
ref: ${{ needs.setup.outputs.branch_name }}
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
||||
with:
|
||||
cache: 'npm'
|
||||
cache-dependency-path: '**/package-lock.json'
|
||||
node-version: ${{ env._NODE_VERSION }}
|
||||
|
||||
- name: Set up Node-gyp
|
||||
run: python3 -m pip install setuptools
|
||||
|
||||
- name: Print environment
|
||||
run: |
|
||||
node --version
|
||||
@@ -765,18 +825,32 @@ jobs:
|
||||
|
||||
- name: Get Build Cache
|
||||
id: build-cache
|
||||
uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1
|
||||
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
with:
|
||||
path: apps/desktop/build
|
||||
key: ${{ runner.os }}-${{ github.run_id }}-build
|
||||
|
||||
- name: Setup Safari Cache
|
||||
id: safari-cache
|
||||
uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1
|
||||
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
with:
|
||||
path: apps/browser/dist/Safari
|
||||
key: ${{ runner.os }}-${{ github.run_id }}-safari-extension
|
||||
|
||||
- name: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Get Azure Key Vault secrets
|
||||
id: get-kv-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: gh-clients
|
||||
secrets: "KEYCHAIN-PASSWORD,APPLE-ID-USERNAME,APPLE-ID-PASSWORD"
|
||||
|
||||
- name: Download Provisioning Profiles secrets
|
||||
env:
|
||||
ACCOUNT_NAME: bitwardenci
|
||||
@@ -795,7 +869,7 @@ jobs:
|
||||
|
||||
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
|
||||
|
||||
@@ -811,9 +885,12 @@ jobs:
|
||||
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: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- name: Set up keychain
|
||||
env:
|
||||
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
|
||||
KEYCHAIN_PASSWORD: ${{ steps.get-kv-secrets.outputs.KEYCHAIN-PASSWORD }}
|
||||
run: |
|
||||
security create-keychain -p $KEYCHAIN_PASSWORD build.keychain
|
||||
security default-keychain -s build.keychain
|
||||
@@ -864,7 +941,7 @@ jobs:
|
||||
|
||||
- name: Download artifact from hotfix-rc
|
||||
if: github.ref == 'refs/heads/hotfix-rc'
|
||||
uses: dawidd6/action-download-artifact@71072fbb1229e1317f1a8de6b04206afb461bd67 # v3.1.2
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
with:
|
||||
workflow: build-browser.yml
|
||||
workflow_conclusion: success
|
||||
@@ -873,7 +950,7 @@ jobs:
|
||||
|
||||
- name: Download artifact from rc
|
||||
if: github.ref == 'refs/heads/rc'
|
||||
uses: dawidd6/action-download-artifact@71072fbb1229e1317f1a8de6b04206afb461bd67 # v3.1.2
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
with:
|
||||
workflow: build-browser.yml
|
||||
workflow_conclusion: success
|
||||
@@ -882,7 +959,7 @@ jobs:
|
||||
|
||||
- name: Download artifact from main
|
||||
if: ${{ github.ref != 'refs/heads/rc' && github.ref != 'refs/heads/hotfix-rc' }}
|
||||
uses: dawidd6/action-download-artifact@71072fbb1229e1317f1a8de6b04206afb461bd67 # v3.1.2
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
with:
|
||||
workflow: build-browser.yml
|
||||
workflow_conclusion: success
|
||||
@@ -903,11 +980,11 @@ jobs:
|
||||
- name: Build application for App Store
|
||||
run: npm run pack:mac:mas
|
||||
env:
|
||||
APPLE_ID_USERNAME: ${{ secrets.APPLE_ID_USERNAME }}
|
||||
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||||
APPLE_ID_USERNAME: ${{ steps.get-kv-secrets.outputs.APPLE-ID-USERNAME }}
|
||||
APPLE_ID_PASSWORD: ${{ steps.get-kv-secrets.outputs.APPLE-ID-PASSWORD }}
|
||||
|
||||
- name: Upload .pkg artifact
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
with:
|
||||
name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.pkg
|
||||
path: apps/desktop/dist/mas-universal/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.pkg
|
||||
@@ -923,6 +1000,10 @@ jobs:
|
||||
- macos-build
|
||||
- macos-package-github
|
||||
- macos-package-mas
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
deployments: write
|
||||
steps:
|
||||
- name: Create GitHub deployment
|
||||
uses: chrnorm/deployment-action@55729fcebec3d284f60f5bcabbd8376437d696b1 # v2.0.7
|
||||
@@ -931,13 +1012,15 @@ jobs:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
initial-status: 'in_progress'
|
||||
environment: 'Desktop - Beta'
|
||||
description: 'Deployment ${{ needs.setup.outputs.release-version }} to channel ${{ needs.setup.outputs.release-channel }} from branch ${{ needs.setup.outputs.branch-name }}'
|
||||
description: 'Deployment ${{ needs.setup.outputs.release_version }} to channel ${{ needs.setup.outputs.release_channel }} from branch ${{ needs.setup.outputs.branch_name }}'
|
||||
task: release
|
||||
|
||||
- name: Login to Azure
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
- name: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
@@ -946,20 +1029,19 @@ jobs:
|
||||
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: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
|
||||
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
|
||||
with:
|
||||
path: apps/desktop/artifacts
|
||||
|
||||
- name: Rename .pkg to .pkg.archive
|
||||
env:
|
||||
PKG_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||
PKG_VERSION: ${{ needs.setup.outputs.release_version }}
|
||||
working-directory: apps/desktop/artifacts
|
||||
run: mv Bitwarden-${{ env.PKG_VERSION }}-universal.pkg Bitwarden-${{ env.PKG_VERSION }}-universal.pkg.archive
|
||||
|
||||
@@ -976,20 +1058,6 @@ 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@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3
|
||||
@@ -1018,9 +1086,11 @@ jobs:
|
||||
- macos-package-github
|
||||
- macos-package-mas
|
||||
- release
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Setup git config
|
||||
run: |
|
||||
@@ -1030,5 +1100,5 @@ jobs:
|
||||
git config --global url."https://".insteadOf ssh://
|
||||
- name: Remove branch
|
||||
env:
|
||||
BRANCH: ${{ needs.setup.outputs.branch-name }}
|
||||
BRANCH: ${{ needs.setup.outputs.branch_name }}
|
||||
run: git push origin --delete $BRANCH
|
||||
|
||||
269
.github/workflows/release-desktop.yml
vendored
269
.github/workflows/release-desktop.yml
vendored
@@ -1,4 +1,3 @@
|
||||
---
|
||||
name: Release Desktop
|
||||
run-name: Release Desktop ${{ inputs.release_type }}
|
||||
|
||||
@@ -6,54 +5,33 @@ 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:
|
||||
shell: bash
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
name: Setup
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
contents: write
|
||||
outputs:
|
||||
release-version: ${{ steps.version.outputs.version }}
|
||||
release-channel: ${{ steps.release-channel.outputs.channel }}
|
||||
release_version: ${{ steps.version.outputs.version }}
|
||||
release_channel: ${{ steps.release_channel.outputs.channel }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Branch check
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
@@ -76,7 +54,7 @@ jobs:
|
||||
monorepo-project: desktop
|
||||
|
||||
- name: Get Version Channel
|
||||
id: release-channel
|
||||
id: release_channel
|
||||
run: |
|
||||
case "${{ steps.version.outputs.version }}" in
|
||||
*"alpha"*)
|
||||
@@ -92,35 +70,6 @@ jobs:
|
||||
;;
|
||||
esac
|
||||
|
||||
- name: Create GitHub deployment
|
||||
if: ${{ github.event.inputs.release_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
|
||||
|
||||
- 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,
|
||||
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@main
|
||||
@@ -145,57 +94,12 @@ 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@main
|
||||
with:
|
||||
packages_dir: "apps/desktop/artifacts"
|
||||
file_path: "apps/desktop/artifacts/sha256-checksums.txt"
|
||||
|
||||
- name: Create Release
|
||||
uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.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@cdcc88a9acf3ca41c16c37bb7d21b9ad48560d87 # v1.15.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 }}
|
||||
RELEASE_CHANNEL: ${{ steps.release_channel.outputs.channel }}
|
||||
with:
|
||||
artifacts: "apps/desktop/artifacts/Bitwarden-${{ env.PKG_VERSION }}-amd64.deb,
|
||||
apps/desktop/artifacts/Bitwarden-${{ env.PKG_VERSION }}-x86_64.rpm,
|
||||
@@ -220,151 +124,10 @@ jobs:
|
||||
apps/desktop/artifacts/Bitwarden-${{ env.PKG_VERSION }}-universal.pkg.archive,
|
||||
apps/desktop/artifacts/${{ env.RELEASE_CHANNEL }}.yml,
|
||||
apps/desktop/artifacts/${{ env.RELEASE_CHANNEL }}-linux.yml,
|
||||
apps/desktop/artifacts/${{ env.RELEASE_CHANNEL }}-mac.yml,
|
||||
apps/desktop/artifacts/sha256-checksums.txt"
|
||||
apps/desktop/artifacts/${{ env.RELEASE_CHANNEL }}-mac.yml"
|
||||
commit: ${{ github.sha }}
|
||||
tag: desktop-v${{ env.PKG_VERSION }}
|
||||
name: Desktop 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@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3
|
||||
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@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3
|
||||
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@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- 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 Snap artifact
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
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@main
|
||||
with:
|
||||
workflow: build-desktop.yml
|
||||
workflow_conclusion: success
|
||||
branch: main
|
||||
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: |
|
||||
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: ${{ github.event.inputs.choco_publish == 'true' }}
|
||||
env:
|
||||
_PKG_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- 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
|
||||
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@main
|
||||
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@main
|
||||
with:
|
||||
workflow: build-desktop.yml
|
||||
workflow_conclusion: success
|
||||
branch: main
|
||||
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
|
||||
|
||||
200
.github/workflows/release-web.yml
vendored
200
.github/workflows/release-web.yml
vendored
@@ -1,4 +1,3 @@
|
||||
---
|
||||
name: Release Web
|
||||
run-name: Release Web ${{ inputs.release_type }}
|
||||
|
||||
@@ -15,19 +14,18 @@ on:
|
||||
- Redeploy
|
||||
- Dry Run
|
||||
|
||||
env:
|
||||
_AZ_REGISTRY: bitwardenprod.azurecr.io
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
name: Setup
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
release_version: ${{ steps.version.outputs.version }}
|
||||
tag_version: ${{ steps.version.outputs.tag }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Branch check
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
@@ -49,182 +47,14 @@ 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@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
########## 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: 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@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
|
||||
- name: Retrieve bot secrets
|
||||
id: retrieve-bot-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: bitwarden-ci
|
||||
secrets: "github-pat-bitwarden-devops-bot-repo-scope"
|
||||
|
||||
- name: Checkout GH pages repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
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@main
|
||||
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@main
|
||||
with:
|
||||
workflow: build-web.yml
|
||||
path: assets
|
||||
workflow_conclusion: success
|
||||
branch: main
|
||||
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 main \
|
||||
--head "${_BRANCH}"
|
||||
else
|
||||
gh pr create --title "Deploy v${_RELEASE_VERSION} to GitHub Pages" \
|
||||
--body "Deploying v${_RELEASE_VERSION}" \
|
||||
--base main \
|
||||
--head "${_BRANCH}"
|
||||
fi
|
||||
|
||||
release:
|
||||
name: Create GitHub Release
|
||||
runs-on: ubuntu-22.04
|
||||
needs:
|
||||
- setup
|
||||
- self-host
|
||||
- ghpages-deploy
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Create GitHub deployment
|
||||
if: ${{ github.event.inputs.release_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: Download latest build artifacts
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
@@ -255,7 +85,7 @@ jobs:
|
||||
|
||||
- name: Create release
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.0
|
||||
uses: ncipollo/release-action@cdcc88a9acf3ca41c16c37bb7d21b9ad48560d87 # v1.15.0
|
||||
with:
|
||||
name: "Web v${{ needs.setup.outputs.release_version }}"
|
||||
commit: ${{ github.sha }}
|
||||
@@ -265,21 +95,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@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: ${{ github.event.inputs.release_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 }}
|
||||
|
||||
482
.github/workflows/repository-management.yml
vendored
Normal file
482
.github/workflows/repository-management.yml
vendored
Normal file
@@ -0,0 +1,482 @@
|
||||
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
|
||||
|
||||
permissions: {}
|
||||
|
||||
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
|
||||
|
||||
bump_version:
|
||||
name: Bump Version
|
||||
if: ${{ always() }}
|
||||
runs-on: ubuntu-24.04
|
||||
needs: 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 }}
|
||||
permissions:
|
||||
id-token: write
|
||||
|
||||
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: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Get Azure Key Vault secrets
|
||||
id: get-kv-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: gh-org-bitwarden
|
||||
secrets: "BW-GHAPP-ID,BW-GHAPP-KEY"
|
||||
|
||||
- name: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- name: Generate GH App token
|
||||
uses: actions/create-github-app-token@30bf6253fa41bdc8d1501d202ad15287582246b4 # v2.0.3
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-ID }}
|
||||
private-key: ${{ steps.get-kv-secrets.outputs.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
|
||||
|
||||
cut_branch:
|
||||
name: Cut branch
|
||||
if: ${{ needs.setup.outputs.branch == 'rc' }}
|
||||
needs:
|
||||
- setup
|
||||
- bump_version
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- name: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Get Azure Key Vault secrets
|
||||
id: get-kv-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: gh-org-bitwarden
|
||||
secrets: "BW-GHAPP-ID,BW-GHAPP-KEY"
|
||||
|
||||
- name: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- name: Generate GH App token
|
||||
uses: actions/create-github-app-token@30bf6253fa41bdc8d1501d202ad15287582246b4 # v2.0.3
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-ID }}
|
||||
private-key: ${{ steps.get-kv-secrets.outputs.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
|
||||
48
.github/workflows/retrieve-current-desktop-rollout.yml
vendored
Normal file
48
.github/workflows/retrieve-current-desktop-rollout.yml
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
name: Retrieve Current Desktop Rollout
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
rollout:
|
||||
name: Retrieve Rollout Percentage
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: 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: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- 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
|
||||
53
.github/workflows/scan.yml
vendored
Normal file
53
.github/workflows/scan.yml
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
name: Scan
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
- "rc"
|
||||
- "hotfix-rc"
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
branches-ignore:
|
||||
- "main"
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened]
|
||||
branches:
|
||||
- "main"
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
check-run:
|
||||
name: Check PR run
|
||||
uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
sast:
|
||||
name: Checkmarx
|
||||
uses: bitwarden/gh-actions/.github/workflows/_checkmarx.yml@main
|
||||
needs: check-run
|
||||
secrets:
|
||||
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
|
||||
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
security-events: write
|
||||
id-token: write
|
||||
|
||||
quality:
|
||||
name: Sonar
|
||||
uses: bitwarden/gh-actions/.github/workflows/_sonar.yml@main
|
||||
needs: check-run
|
||||
secrets:
|
||||
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
|
||||
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
id-token: write
|
||||
58
.github/workflows/staged-rollout-desktop.yml
vendored
58
.github/workflows/staged-rollout-desktop.yml
vendored
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: Staged Rollout Desktop
|
||||
run-name: Staged Rollout Desktop - ${{ inputs.rollout_percentage }}%
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
@@ -18,11 +18,15 @@ jobs:
|
||||
rollout:
|
||||
name: Update Rollout Percentage
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Login to Azure
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
- name: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
@@ -31,29 +35,24 @@ jobs:
|
||||
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: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- 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 +94,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
|
||||
|
||||
8
.github/workflows/stale-bot.yml
vendored
8
.github/workflows/stale-bot.yml
vendored
@@ -1,4 +1,3 @@
|
||||
---
|
||||
name: 'Close stale issues and PRs'
|
||||
on:
|
||||
workflow_dispatch:
|
||||
@@ -9,9 +8,14 @@ jobs:
|
||||
stale:
|
||||
name: 'Check for stale issues and PRs'
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
actions: write
|
||||
contents: read
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: 'Run stale action'
|
||||
uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # v9.0.0
|
||||
uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0
|
||||
with:
|
||||
stale-issue-label: 'needs-reply'
|
||||
stale-pr-label: 'needs-changes'
|
||||
|
||||
135
.github/workflows/test.yml
vendored
135
.github/workflows/test.yml
vendored
@@ -1,5 +1,4 @@
|
||||
---
|
||||
name: Run tests
|
||||
name: Testing
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
@@ -9,18 +8,23 @@ on:
|
||||
- "rc"
|
||||
- "hotfix-rc-*"
|
||||
pull_request:
|
||||
types: [ opened, synchronize ]
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
test:
|
||||
|
||||
testing:
|
||||
name: Run tests
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
checks: write
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Get Node Version
|
||||
id: retrieve-node-version
|
||||
@@ -30,7 +34,7 @@ jobs:
|
||||
echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
||||
with:
|
||||
cache: 'npm'
|
||||
cache-dependency-path: '**/package-lock.json'
|
||||
@@ -48,55 +52,63 @@ jobs:
|
||||
# Tests in apps/ are typechecked when their app is built, so we just do it here for libs/
|
||||
# See https://bitwarden.atlassian.net/browse/EC-497
|
||||
- name: Run typechecking
|
||||
run: npm run test:types --coverage
|
||||
run: npm run test:types
|
||||
|
||||
- name: Run tests
|
||||
run: npm run test --coverage
|
||||
# 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@eaa763f6ffc21c7a37837f56cd5f9737f27fc6c8 # v1.8.0
|
||||
if: always()
|
||||
uses: dorny/test-reporter@6e6a65b7a0bd2c9197df7d0ae36ac5cee784230c # v2.0.0
|
||||
if: ${{ github.event.pull_request.head.repo.full_name == github.repository && !cancelled() }}
|
||||
with:
|
||||
name: Test Results
|
||||
path: "junit.xml"
|
||||
reporter: jest-junit
|
||||
fail-on-error: true
|
||||
|
||||
- name: Upload to codecov.io
|
||||
uses: codecov/codecov-action@54bcd8715eee62d40e33596ef5e8f0f48dbbccab # v4.1.0
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
- name: Upload results to codecov.io
|
||||
uses: codecov/test-results-action@f2dba722c67b86c6caa034178c6e4d35335f6706 # v1.1.0
|
||||
|
||||
- name: Upload test coverage
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
with:
|
||||
name: jest-coverage
|
||||
path: ./coverage/lcov.info
|
||||
|
||||
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
|
||||
- macos-latest
|
||||
- windows-latest
|
||||
- ubuntu-22.04
|
||||
- macos-14
|
||||
- windows-2022
|
||||
|
||||
steps:
|
||||
- name: Rust version check
|
||||
- name: Check Rust version
|
||||
run: rustup --version
|
||||
|
||||
- name: Install gnome-keyring
|
||||
if: ${{ matrix.os=='ubuntu-latest' }}
|
||||
if: ${{ matrix.os=='ubuntu-22.04' }}
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y gnome-keyring dbus-x11
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Build
|
||||
working-directory: ./apps/desktop/desktop_native
|
||||
run: cargo build
|
||||
|
||||
- name: Test Ubuntu
|
||||
if: ${{ matrix.os=='ubuntu-latest' }}
|
||||
if: ${{ matrix.os=='ubuntu-22.04' }}
|
||||
working-directory: ./apps/desktop/desktop_native
|
||||
run: |
|
||||
eval "$(dbus-launch --sh-syntax)"
|
||||
@@ -106,7 +118,72 @@ 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-14' }}
|
||||
working-directory: ./apps/desktop/desktop_native
|
||||
run: cargo test -- --test-threads=1
|
||||
|
||||
- name: Test Windows
|
||||
if: ${{ matrix.os=='windows-2022'}}
|
||||
working-directory: ./apps/desktop/desktop_native/core
|
||||
run: cargo test -- --test-threads=1
|
||||
|
||||
rust-coverage:
|
||||
name: Rust Coverage
|
||||
runs-on: macos-14
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Install rust
|
||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # stable
|
||||
with:
|
||||
toolchain: stable
|
||||
components: llvm-tools
|
||||
|
||||
- name: Cache cargo registry
|
||||
uses: Swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab # v2.7.5
|
||||
with:
|
||||
workspaces: "apps/desktop/desktop_native -> target"
|
||||
|
||||
- name: Install cargo-llvm-cov
|
||||
run: cargo install cargo-llvm-cov --version 0.6.16
|
||||
|
||||
- name: Generate coverage
|
||||
working-directory: ./apps/desktop/desktop_native
|
||||
run: cargo llvm-cov --all-features --lcov --output-path lcov.info --workspace --no-cfg-coverage
|
||||
|
||||
- name: Upload test coverage
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
with:
|
||||
name: rust-coverage
|
||||
path: ./apps/desktop/desktop_native/lcov.info
|
||||
|
||||
upload-codecov:
|
||||
name: Upload to Codecov
|
||||
runs-on: ubuntu-22.04
|
||||
needs:
|
||||
- testing
|
||||
- rust-coverage
|
||||
steps:
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Download jest coverage
|
||||
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
|
||||
with:
|
||||
name: jest-coverage
|
||||
path: ./
|
||||
|
||||
- name: Download rust coverage
|
||||
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
|
||||
with:
|
||||
name: rust-coverage
|
||||
path: ./apps/desktop/desktop_native
|
||||
|
||||
- name: Upload coverage to codecov.io
|
||||
uses: codecov/codecov-action@ad3126e916f78f00edff4ed0317cf185271ccc2d # v5.4.2
|
||||
with:
|
||||
files: |
|
||||
./lcov.info
|
||||
./apps/desktop/desktop_native/lcov.info
|
||||
|
||||
106
.github/workflows/version-auto-bump.yml
vendored
106
.github/workflows/version-auto-bump.yml
vendored
@@ -1,4 +1,3 @@
|
||||
---
|
||||
name: Auto Bump Desktop Version
|
||||
|
||||
on:
|
||||
@@ -6,53 +5,78 @@ on:
|
||||
tags:
|
||||
- desktop-v**
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
bump-version:
|
||||
name: Bump Desktop Version
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout Branch
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- name: Calculate bumped version
|
||||
id: version
|
||||
env:
|
||||
RELEASE_TAG: ${{ github.ref }}
|
||||
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"
|
||||
|
||||
NEW_PATCH=$((CURR_PATCH+1))
|
||||
|
||||
echo "New patch: $NEW_PATCH"
|
||||
|
||||
NEW_VER=$CURR_MAJOR.$NEW_PATCH
|
||||
echo "New Version: $NEW_VER"
|
||||
echo "New Version: $NEW_VER" >> $GITHUB_STEP_SUMMARY
|
||||
echo "new_version=$NEW_VER" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Login to Azure - CI Subscription
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
- name: Log in to Azure
|
||||
uses: bitwarden/gh-actions/azure-login@main
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client_id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
|
||||
- name: Retrieve bot secrets
|
||||
id: retrieve-bot-secrets
|
||||
- name: Get Azure Key Vault secrets
|
||||
id: get-kv-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: bitwarden-ci
|
||||
secrets: "github-pat-bitwarden-devops-bot-repo-scope"
|
||||
keyvault: gh-org-bitwarden
|
||||
secrets: "BW-GHAPP-ID,BW-GHAPP-KEY"
|
||||
|
||||
- name: "Bump version to ${{ steps.version.outputs.new_version }}"
|
||||
env:
|
||||
GH_TOKEN: ${{ steps.retrieve-bot-secrets.outputs.github-pat-bitwarden-devops-bot-repo-scope }}
|
||||
- name: Log out from Azure
|
||||
uses: bitwarden/gh-actions/azure-logout@main
|
||||
|
||||
- name: Generate GH App token
|
||||
uses: actions/create-github-app-token@30bf6253fa41bdc8d1501d202ad15287582246b4 # v2.0.3
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-ID }}
|
||||
private-key: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-KEY }}
|
||||
|
||||
- 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: |
|
||||
echo '{"cut_rc_branch": "false", "version_number": "${{ steps.version.outputs.new_version }}",
|
||||
"bump_browser": "false", "bump_cli": "false", "bump_desktop": "true", "bump_web": "false"}' | \
|
||||
gh workflow run version-bump.yml --json --repo bitwarden/clients
|
||||
git config --local user.email "actions@github.com"
|
||||
git config --local user.name "Github Actions"
|
||||
|
||||
- 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
|
||||
|
||||
- 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 }}
|
||||
|
||||
- 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
|
||||
|
||||
- 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
|
||||
|
||||
394
.github/workflows/version-bump.yml
vendored
394
.github/workflows/version-bump.yml
vendored
@@ -1,394 +0,0 @@
|
||||
---
|
||||
name: Version Bump
|
||||
run-name: Version Bump - v${{ inputs.version_number }}
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
bump_browser:
|
||||
description: "Bump Browser?"
|
||||
type: boolean
|
||||
default: false
|
||||
bump_cli:
|
||||
description: "Bump CLI?"
|
||||
type: boolean
|
||||
default: false
|
||||
bump_desktop:
|
||||
description: "Bump Desktop?"
|
||||
type: boolean
|
||||
default: false
|
||||
bump_web:
|
||||
description: "Bump Web?"
|
||||
type: boolean
|
||||
default: false
|
||||
version_number:
|
||||
description: "New version (example: '2024.1.0')"
|
||||
required: true
|
||||
cut_rc_branch:
|
||||
description: "Cut RC branch?"
|
||||
default: true
|
||||
type: boolean
|
||||
|
||||
jobs:
|
||||
bump_version:
|
||||
name: "Bump Version to v${{ inputs.version_number }}"
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Login to Azure - Prod Subscription
|
||||
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: "github-gpg-private-key,
|
||||
github-gpg-private-key-passphrase,
|
||||
github-pat-bitwarden-devops-bot-repo-scope"
|
||||
|
||||
- name: Checkout Branch
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
ref: main
|
||||
|
||||
- name: Check if RC branch exists
|
||||
if: ${{ inputs.cut_rc_branch == true }}
|
||||
run: |
|
||||
remote_rc_branch_check=$(git ls-remote --heads origin rc | wc -l)
|
||||
if [[ "${remote_rc_branch_check}" -gt 0 ]]; then
|
||||
echo "Remote RC branch exists."
|
||||
echo "Please delete current RC branch before running again."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Import GPG key
|
||||
uses: crazy-max/ghaction-import-gpg@01dd5d3ca463c7f10f7f4f7b4f177225ac661ee4 # v6.1.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: create-branch
|
||||
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
|
||||
|
||||
NAME=version_bump_${{ github.ref_name }}_${{ inputs.version_number }}
|
||||
git switch -c $NAME
|
||||
echo "name=$NAME" >> $GITHUB_OUTPUT
|
||||
|
||||
########################
|
||||
# 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."
|
||||
else
|
||||
echo "Version check failed."
|
||||
exit 1
|
||||
fi
|
||||
working-directory: apps/browser
|
||||
|
||||
- name: Bump Browser Version
|
||||
if: ${{ inputs.bump_browser == true }}
|
||||
run: npm version --workspace=@bitwarden/browser ${{ inputs.version_number }}
|
||||
|
||||
- name: Bump Browser Version - Manifest
|
||||
if: ${{ inputs.bump_browser == true }}
|
||||
uses: bitwarden/gh-actions/version-bump@main
|
||||
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@main
|
||||
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."
|
||||
else
|
||||
echo "Version check failed."
|
||||
exit 1
|
||||
fi
|
||||
working-directory: apps/cli
|
||||
|
||||
- name: Bump CLI Version
|
||||
if: ${{ inputs.bump_cli == true }}
|
||||
run: npm version --workspace=@bitwarden/cli ${{ inputs.version_number }}
|
||||
|
||||
### 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."
|
||||
else
|
||||
echo "Version check failed."
|
||||
exit 1
|
||||
fi
|
||||
working-directory: apps/desktop
|
||||
|
||||
- name: Bump Desktop Version - Root
|
||||
if: ${{ inputs.bump_desktop == true }}
|
||||
run: npm version --workspace=@bitwarden/desktop ${{ inputs.version_number }}
|
||||
|
||||
- name: Bump Desktop Version - App
|
||||
if: ${{ inputs.bump_desktop == true }}
|
||||
run: npm version ${{ inputs.version_number }}
|
||||
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."
|
||||
else
|
||||
echo "Version check failed."
|
||||
exit 1
|
||||
fi
|
||||
working-directory: apps/web
|
||||
|
||||
- name: Bump Web Version
|
||||
if: ${{ inputs.bump_web == true }}
|
||||
run: npm version --workspace=@bitwarden/web-vault ${{ inputs.version_number }}
|
||||
|
||||
########################
|
||||
|
||||
- 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.create-branch.outputs.client }}
|
||||
VERSION: ${{ inputs.version_number }}
|
||||
run: git commit -m "Bumped ${CLIENT} version to ${VERSION}" -a
|
||||
|
||||
- name: Push changes
|
||||
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }}
|
||||
env:
|
||||
PR_BRANCH: ${{ steps.create-branch.outputs.name }}
|
||||
run: git push -u origin $PR_BRANCH
|
||||
|
||||
- name: Create Version PR
|
||||
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }}
|
||||
id: create-pr
|
||||
env:
|
||||
GH_TOKEN: ${{ steps.retrieve-secrets.outputs.github-pat-bitwarden-devops-bot-repo-scope }}
|
||||
PR_BRANCH: ${{ steps.create-branch.outputs.name }}
|
||||
TITLE: "Bump ${{ steps.create-branch.outputs.client }} version to ${{ inputs.version_number }}"
|
||||
run: |
|
||||
PR_URL=$(gh pr create --title "$TITLE" \
|
||||
--base "main" \
|
||||
--head "$PR_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.create-branch.outputs.client }} version bump to ${{ inputs.version_number }}")
|
||||
echo "pr_number=${PR_URL##*/}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Approve PR
|
||||
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }}
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PR_NUMBER: ${{ steps.create-pr.outputs.pr_number }}
|
||||
run: gh pr review $PR_NUMBER --approve
|
||||
|
||||
- name: Merge PR
|
||||
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }}
|
||||
env:
|
||||
GH_TOKEN: ${{ steps.retrieve-secrets.outputs.github-pat-bitwarden-devops-bot-repo-scope }}
|
||||
PR_NUMBER: ${{ steps.create-pr.outputs.pr_number }}
|
||||
run: gh pr merge $PR_NUMBER --squash --auto --delete-branch
|
||||
|
||||
cut_rc:
|
||||
name: Cut RC branch
|
||||
needs: bump_version
|
||||
if: ${{ inputs.cut_rc_branch == true }}
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout Branch
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
ref: main
|
||||
|
||||
### Browser
|
||||
- name: Browser - Verify version has been updated
|
||||
if: ${{ inputs.bump_browser == true }}
|
||||
env:
|
||||
NEW_VERSION: ${{ inputs.version_number }}
|
||||
run: |
|
||||
# Wait for version to change.
|
||||
while : ; do
|
||||
echo "Waiting for version to be updated..."
|
||||
git pull --force
|
||||
CURRENT_VERSION=$(cat package.json | jq -r '.version')
|
||||
|
||||
# If the versions don't match we continue the loop, otherwise we break out of the loop.
|
||||
[[ "$NEW_VERSION" != "$CURRENT_VERSION" ]] || break
|
||||
sleep 10
|
||||
done
|
||||
working-directory: apps/browser
|
||||
|
||||
### CLI
|
||||
- name: CLI - Verify version has been updated
|
||||
if: ${{ inputs.bump_cli == true }}
|
||||
env:
|
||||
NEW_VERSION: ${{ inputs.version_number }}
|
||||
run: |
|
||||
# Wait for version to change.
|
||||
while : ; do
|
||||
echo "Waiting for version to be updated..."
|
||||
git pull --force
|
||||
CURRENT_VERSION=$(cat package.json | jq -r '.version')
|
||||
|
||||
# If the versions don't match we continue the loop, otherwise we break out of the loop.
|
||||
[[ "$NEW_VERSION" != "$CURRENT_VERSION" ]] || break
|
||||
sleep 10
|
||||
done
|
||||
working-directory: apps/cli
|
||||
|
||||
### Desktop
|
||||
- name: Desktop - Verify version has been updated
|
||||
if: ${{ inputs.bump_desktop == true }}
|
||||
env:
|
||||
NEW_VERSION: ${{ inputs.version_number }}
|
||||
run: |
|
||||
# Wait for version to change.
|
||||
while : ; do
|
||||
echo "Waiting for version to be updated..."
|
||||
git pull --force
|
||||
CURRENT_VERSION=$(cat package.json | jq -r '.version')
|
||||
|
||||
# If the versions don't match we continue the loop, otherwise we break out of the loop.
|
||||
[[ "$NEW_VERSION" != "$CURRENT_VERSION" ]] || break
|
||||
sleep 10
|
||||
done
|
||||
working-directory: apps/desktop
|
||||
|
||||
### Web
|
||||
- name: Web - Verify version has been updated
|
||||
if: ${{ inputs.bump_web == true }}
|
||||
env:
|
||||
NEW_VERSION: ${{ inputs.version_number }}
|
||||
run: |
|
||||
# Wait for version to change.
|
||||
while : ; do
|
||||
echo "Waiting for version to be updated..."
|
||||
git pull --force
|
||||
CURRENT_VERSION=$(cat package.json | jq -r '.version')
|
||||
|
||||
# If the versions don't match we continue the loop, otherwise we break out of the loop.
|
||||
[[ "$NEW_VERSION" != "$CURRENT_VERSION" ]] || break
|
||||
sleep 10
|
||||
done
|
||||
working-directory: apps/web
|
||||
|
||||
- name: Cut RC branch
|
||||
run: |
|
||||
git switch --quiet --create rc
|
||||
git push --quiet --set-upstream origin rc
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
@@ -27,10 +27,16 @@ npm-debug.log
|
||||
dist
|
||||
build
|
||||
.angular/cache
|
||||
.flatpak
|
||||
.flatpak-repo
|
||||
.flatpak-builder
|
||||
|
||||
# Testing
|
||||
coverage
|
||||
junit.xml
|
||||
## The "base" root level folder is expected for some local tests that do
|
||||
## comparisons between the current branch and a base branch (usually main)
|
||||
base/
|
||||
|
||||
# Misc
|
||||
*.crx
|
||||
@@ -45,3 +51,6 @@ storybook-static
|
||||
|
||||
# Local app configuration
|
||||
apps/**/config/local.json
|
||||
|
||||
# Nx
|
||||
.nx
|
||||
|
||||
33
.storybook/format-args-for-code-snippet.ts
Normal file
33
.storybook/format-args-for-code-snippet.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { argsToTemplate, StoryObj } from "@storybook/angular";
|
||||
|
||||
type RenderArgType<T> = StoryObj<T>["args"];
|
||||
|
||||
export const formatArgsForCodeSnippet = <ComponentType extends Record<string, any>>(
|
||||
args: RenderArgType<ComponentType>,
|
||||
) => {
|
||||
const nonNullArgs = Object.entries(args as ComponentType).filter(
|
||||
([_, value]) => value !== null && value !== undefined,
|
||||
);
|
||||
const functionArgs = nonNullArgs.filter(([_, value]) => typeof value === "function");
|
||||
const argsToFormat = nonNullArgs.filter(([_, value]) => typeof value !== "function");
|
||||
|
||||
const argsToTemplateIncludeKeys = [...functionArgs].map(
|
||||
([key, _]) => key as keyof RenderArgType<ComponentType>,
|
||||
);
|
||||
|
||||
const formattedNonFunctionArgs = argsToFormat
|
||||
.map(([key, value]) => {
|
||||
if (typeof value === "boolean") {
|
||||
return `[${key}]="${value}"`;
|
||||
}
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
const formattedArray = value.map((v) => `'${v}'`).join(", ");
|
||||
return `[${key}]="[${formattedArray}]"`;
|
||||
}
|
||||
return `${key}="${value}"`;
|
||||
})
|
||||
.join(" ");
|
||||
|
||||
return `${formattedNonFunctionArgs} ${argsToTemplate(args as ComponentType, { include: argsToTemplateIncludeKeys })}`;
|
||||
};
|
||||
@@ -1,24 +1,39 @@
|
||||
import { dirname, join } from "path";
|
||||
|
||||
import { StorybookConfig } from "@storybook/angular";
|
||||
import TsconfigPathsPlugin from "tsconfig-paths-webpack-plugin";
|
||||
import remarkGfm from "remark-gfm";
|
||||
import TsconfigPathsPlugin from "tsconfig-paths-webpack-plugin";
|
||||
|
||||
const config: StorybookConfig = {
|
||||
stories: [
|
||||
"../libs/auth/src/**/*.mdx",
|
||||
"../libs/auth/src/**/*.stories.@(js|jsx|ts|tsx)",
|
||||
"../libs/dirt/card/src/**/*.mdx",
|
||||
"../libs/dirt/card/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/angular/src/**/*.stories.@(js|jsx|ts|tsx)",
|
||||
],
|
||||
addons: [
|
||||
"@storybook/addon-links",
|
||||
"@storybook/addon-essentials",
|
||||
"@storybook/addon-a11y",
|
||||
"@storybook/addon-designs",
|
||||
"@storybook/addon-interactions",
|
||||
getAbsolutePath("@storybook/addon-links"),
|
||||
getAbsolutePath("@storybook/addon-essentials"),
|
||||
getAbsolutePath("@storybook/addon-a11y"),
|
||||
getAbsolutePath("@storybook/addon-designs"),
|
||||
getAbsolutePath("@storybook/addon-interactions"),
|
||||
getAbsolutePath("@storybook/addon-themes"),
|
||||
{
|
||||
// @storybook/addon-docs is part of @storybook/addon-essentials
|
||||
// eslint-disable-next-line storybook/no-uninstalled-addons
|
||||
name: "@storybook/addon-docs",
|
||||
options: {
|
||||
mdxPluginOptions: {
|
||||
@@ -30,7 +45,7 @@ const config: StorybookConfig = {
|
||||
},
|
||||
],
|
||||
framework: {
|
||||
name: "@storybook/angular",
|
||||
name: getAbsolutePath("@storybook/angular"),
|
||||
options: {},
|
||||
},
|
||||
core: {
|
||||
@@ -38,9 +53,7 @@ const config: StorybookConfig = {
|
||||
},
|
||||
env: (config) => ({
|
||||
...config,
|
||||
FLAGS: JSON.stringify({
|
||||
secretsManager: true,
|
||||
}),
|
||||
FLAGS: JSON.stringify({}),
|
||||
}),
|
||||
webpackFinal: async (config, { configType }) => {
|
||||
if (config.resolve) {
|
||||
@@ -48,9 +61,13 @@ const config: StorybookConfig = {
|
||||
}
|
||||
return config;
|
||||
},
|
||||
docs: {
|
||||
autodocs: true,
|
||||
},
|
||||
docs: {},
|
||||
staticDirs: ["../apps/web/src/images"],
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
||||
// Recommended for mono-repositories
|
||||
function getAbsolutePath(value: string): any {
|
||||
return dirname(require.resolve(join(value, "package.json")));
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { addons } from "@storybook/addons";
|
||||
import { addons } from "@storybook/manager-api";
|
||||
import { create } from "@storybook/theming/create";
|
||||
|
||||
const lightTheme = create({
|
||||
@@ -50,10 +50,14 @@ const darkTheme = create({
|
||||
});
|
||||
|
||||
export const getPreferredColorScheme = () => {
|
||||
if (!globalThis || !globalThis.matchMedia) return "light";
|
||||
if (!globalThis || !globalThis.matchMedia) {
|
||||
return "light";
|
||||
}
|
||||
|
||||
const isDarkThemePreferred = globalThis.matchMedia("(prefers-color-scheme: dark)").matches;
|
||||
if (isDarkThemePreferred) return "dark";
|
||||
if (isDarkThemePreferred) {
|
||||
return "dark";
|
||||
}
|
||||
|
||||
return "light";
|
||||
};
|
||||
|
||||
@@ -1,98 +1,34 @@
|
||||
import { setCompodocJson } from "@storybook/addon-docs/angular";
|
||||
import { withThemeByClassName } from "@storybook/addon-themes";
|
||||
import { componentWrapperDecorator } from "@storybook/angular";
|
||||
import type { Preview } from "@storybook/angular";
|
||||
|
||||
import docJson from "../documentation.json";
|
||||
setCompodocJson(docJson);
|
||||
|
||||
const decorator = componentWrapperDecorator(
|
||||
(story) => {
|
||||
return `
|
||||
<ng-template #lightPreview>
|
||||
<div
|
||||
class="theme_light tw-border-2 tw-border-solid tw-border-secondary-300 tw-bg-[#ffffff] tw-px-5 tw-py-10 tw-mb-5"
|
||||
*ngIf="theme == 'both' || theme == 'light'"
|
||||
>
|
||||
${story}
|
||||
</div>
|
||||
</ng-template>
|
||||
<ng-template #darkPreview>
|
||||
<div
|
||||
class="theme_dark tw-border-2 tw-border-solid tw-bg-[#1f242e] tw-px-5 tw-py-10"
|
||||
*ngIf="theme == 'both' || theme == 'dark'"
|
||||
>
|
||||
${story}
|
||||
</div>
|
||||
</ng-template>
|
||||
<ng-template #nordPreview>
|
||||
<div
|
||||
class="theme_nord tw-border-2 tw-border-solid tw-bg-[#434C5E] tw-px-5 tw-py-10"
|
||||
*ngIf="theme == 'nord'">
|
||||
${story}
|
||||
</div>
|
||||
</ng-template>
|
||||
<ng-template #solarizedPreview>
|
||||
<div
|
||||
class="theme_solarized tw-border-2 tw-border-solid tw-bg-[#002b36] tw-px-5 tw-py-10"
|
||||
*ngIf="theme == 'solarized'"
|
||||
>
|
||||
${story}
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<ng-container *ngTemplateOutlet="lightPreview"></ng-container>
|
||||
<ng-container *ngTemplateOutlet="darkPreview"></ng-container>
|
||||
<ng-container *ngTemplateOutlet="nordPreview"></ng-container>
|
||||
<ng-container *ngTemplateOutlet="solarizedPreview"></ng-container>
|
||||
const wrapperDecorator = componentWrapperDecorator((story) => {
|
||||
return /*html*/ `
|
||||
<div class="tw-bg-background tw-px-5 tw-py-10">
|
||||
${story}
|
||||
</div>
|
||||
`;
|
||||
},
|
||||
({ globals }) => {
|
||||
return { theme: `${globals["theme"]}` };
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
const preview: Preview = {
|
||||
decorators: [decorator],
|
||||
globalTypes: {
|
||||
theme: {
|
||||
description: "Global theme for components",
|
||||
defaultValue: "both",
|
||||
toolbar: {
|
||||
title: "Theme",
|
||||
icon: "circlehollow",
|
||||
items: [
|
||||
{
|
||||
title: "Light & Dark",
|
||||
value: "both",
|
||||
icon: "sidebyside",
|
||||
},
|
||||
{
|
||||
title: "Light",
|
||||
value: "light",
|
||||
icon: "sun",
|
||||
},
|
||||
{
|
||||
title: "Dark",
|
||||
value: "dark",
|
||||
icon: "moon",
|
||||
},
|
||||
{
|
||||
title: "Nord",
|
||||
value: "nord",
|
||||
left: "⛰",
|
||||
},
|
||||
{
|
||||
title: "Solarized",
|
||||
value: "solarized",
|
||||
left: "☯",
|
||||
},
|
||||
],
|
||||
dynamicTitle: true,
|
||||
decorators: [
|
||||
withThemeByClassName({
|
||||
themes: {
|
||||
light: "theme_light",
|
||||
dark: "theme_dark",
|
||||
},
|
||||
},
|
||||
},
|
||||
defaultTheme: "light",
|
||||
}),
|
||||
wrapperDecorator,
|
||||
],
|
||||
parameters: {
|
||||
actions: { argTypesRegex: "^on[A-Z].*" },
|
||||
a11y: {
|
||||
element: "#storybook-root",
|
||||
},
|
||||
controls: {
|
||||
matchers: {
|
||||
color: /(background|color)$/i,
|
||||
@@ -105,8 +41,17 @@ const preview: Preview = {
|
||||
order: ["Documentation", ["Introduction", "Colors", "Icons"], "Component Library"],
|
||||
},
|
||||
},
|
||||
docs: { source: { type: "dynamic", excludeDecorators: true } },
|
||||
docs: {
|
||||
source: {
|
||||
type: "dynamic",
|
||||
excludeDecorators: true,
|
||||
},
|
||||
},
|
||||
backgrounds: {
|
||||
disable: true,
|
||||
},
|
||||
},
|
||||
tags: ["autodocs"],
|
||||
};
|
||||
|
||||
export default preview;
|
||||
|
||||
47
.storybook/test-runner.ts
Normal file
47
.storybook/test-runner.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { type TestRunnerConfig } from "@storybook/test-runner";
|
||||
import { injectAxe, checkA11y } from "axe-playwright";
|
||||
|
||||
const testRunnerConfig: TestRunnerConfig = {
|
||||
setup() {},
|
||||
|
||||
async preVisit(page, context) {
|
||||
return await injectAxe(page);
|
||||
},
|
||||
|
||||
async postVisit(page, context) {
|
||||
await page.waitForSelector("#storybook-root");
|
||||
// https://github.com/abhinaba-ghosh/axe-playwright#parameters-on-checka11y-axerun
|
||||
await checkA11y(
|
||||
// Playwright page instance.
|
||||
page,
|
||||
|
||||
// context
|
||||
"#storybook-root",
|
||||
|
||||
// axeOptions, see https://www.deque.com/axe/core-documentation/api-documentation/#parameters-axerun
|
||||
{
|
||||
detailedReport: true,
|
||||
detailedReportOptions: {
|
||||
// Includes the full html for invalid nodes
|
||||
html: true,
|
||||
},
|
||||
verbose: false,
|
||||
},
|
||||
|
||||
// skipFailures
|
||||
false,
|
||||
|
||||
// reporter "v2" is terminal reporter, "html" writes results to file
|
||||
"v2",
|
||||
|
||||
// axeHtmlReporterOptions
|
||||
// NOTE: set reporter param (above) to "html" to activate these options
|
||||
{
|
||||
outputDir: "reports/a11y",
|
||||
reportFileName: `${context.id}.html`,
|
||||
},
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export default testRunnerConfig;
|
||||
@@ -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"
|
||||
|
||||
4
.storybook/typings.d.ts
vendored
4
.storybook/typings.d.ts
vendored
@@ -1,4 +0,0 @@
|
||||
declare module "*.md" {
|
||||
const content: string;
|
||||
export default content;
|
||||
}
|
||||
7
.vscode/settings.json
vendored
7
.vscode/settings.json
vendored
@@ -1,9 +1,12 @@
|
||||
{
|
||||
"cSpell.words": ["Csprng", "decryptable", "Popout", "Reprompt", "takeuntil"],
|
||||
"cSpell.words": ["Csprng", "Decapsulation", "decryptable", "Popout", "Reprompt", "takeuntil"],
|
||||
"search.exclude": {
|
||||
"**/locales/[^e]*/messages.json": true,
|
||||
"**/locales/*[^n]/messages.json": true,
|
||||
"**/_locales/[^e]*/messages.json": true,
|
||||
"**/_locales/*[^n]/messages.json": true
|
||||
}
|
||||
},
|
||||
"rust-analyzer.linkedProjects": ["apps/desktop/desktop_native/Cargo.toml"],
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"eslint.useFlatConfig": true
|
||||
}
|
||||
|
||||
@@ -5,13 +5,13 @@ specifies another license. Bitwarden Licensed code is found only in the
|
||||
/bitwarden_license directory.
|
||||
|
||||
GPL v3.0:
|
||||
https://github.com/bitwarden/web/blob/master/LICENSE_GPL.txt
|
||||
https://github.com/bitwarden/clients/blob/main/LICENSE_GPL.txt
|
||||
|
||||
Bitwarden License v1.0:
|
||||
https://github.com/bitwarden/web/blob/master/LICENSE_BITWARDEN.txt
|
||||
https://github.com/bitwarden/clients/blob/main/LICENSE_BITWARDEN.txt
|
||||
|
||||
No grant of any rights in the trademarks, service marks, or logos of Bitwarden is
|
||||
made (except as may be necessary to comply with the notice requirements as
|
||||
applicable), and use of any Bitwarden trademarks must comply with Bitwarden
|
||||
Trademark Guidelines
|
||||
<https://github.com/bitwarden/server/blob/master/TRADEMARK_GUIDELINES.md>.
|
||||
<https://github.com/bitwarden/server/blob/main/TRADEMARK_GUIDELINES.md>.
|
||||
|
||||
@@ -56,7 +56,7 @@ such Open Source Software only.
|
||||
logos of any Contributor (except as may be necessary to comply with the notice
|
||||
requirements in Section 2.3), and use of any Bitwarden trademarks must comply with
|
||||
Bitwarden Trademark Guidelines
|
||||
<https://github.com/bitwarden/server/blob/master/TRADEMARK_GUIDELINES.md>.
|
||||
<https://github.com/bitwarden/server/blob/main/TRADEMARK_GUIDELINES.md>.
|
||||
|
||||
3. TERMINATION
|
||||
|
||||
|
||||
@@ -13,14 +13,15 @@
|
||||
|
||||
# Bitwarden Client Applications
|
||||
|
||||
This repository houses all Bitwarden client applications except the [Mobile application](https://github.com/bitwarden/mobile).
|
||||
This repository houses all Bitwarden client applications except the mobile applications ([iOS](https://github.com/bitwarden/ios) | [android](https://github.com/bitwarden/android)).
|
||||
|
||||
Please refer to the [Clients section](https://contributing.bitwarden.com/getting-started/clients/) of the [Contributing Documentation](https://contributing.bitwarden.com/) for build instructions, recommended tooling, code style tips, and lots of other great information to get you started.
|
||||
|
||||
## 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 iOS Password Manager & Authenticator apps.
|
||||
- [bitwarden/android](https://github.com/bitwarden/android): Bitwarden Android Password Manager & Authenticator apps.
|
||||
- [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!
|
||||
|
||||
62
angular.json
62
angular.json
@@ -6,6 +6,32 @@
|
||||
"analytics": false
|
||||
},
|
||||
"projects": {
|
||||
"bit-web": {
|
||||
"projectType": "application",
|
||||
"schematics": {
|
||||
"@schematics/angular:application": {
|
||||
"strict": true
|
||||
}
|
||||
},
|
||||
"root": "bitwarden_license/bit-web",
|
||||
"sourceRoot": "bitwarden_license/bit-web/src",
|
||||
"prefix": "app",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"outputPath": "dist/web",
|
||||
"index": "apps/web/src/index.html",
|
||||
"main": "bitwarden_license/bit-web/src/app/main.ts",
|
||||
"polyfills": "apps/web/src/polyfills.ts",
|
||||
"tsConfig": "bitwarden_license/bit-web/tsconfig.json",
|
||||
"assets": ["apps/web/src/favicon.ico"],
|
||||
"styles": [],
|
||||
"scripts": []
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"web": {
|
||||
"projectType": "application",
|
||||
"schematics": {
|
||||
@@ -22,8 +48,8 @@
|
||||
"options": {
|
||||
"outputPath": "dist/web",
|
||||
"index": "apps/web/src/index.html",
|
||||
"main": "apps/web/src/app/main.ts",
|
||||
"polyfills": "apps/web/src/app/polyfills.ts",
|
||||
"main": "apps/web/src/main.ts",
|
||||
"polyfills": "apps/web/src/polyfills.ts",
|
||||
"tsConfig": "apps/web/tsconfig.json",
|
||||
"assets": ["apps/web/src/favicon.ico"],
|
||||
"styles": [],
|
||||
@@ -128,10 +154,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 +168,19 @@
|
||||
"configDir": ".storybook",
|
||||
"browserTarget": "components:build",
|
||||
"compodoc": true,
|
||||
"compodocArgs": ["-p", "./tsconfig.json", "-e", "json", "-d", "."],
|
||||
"compodocArgs": [
|
||||
"-p",
|
||||
"./tsconfig.json",
|
||||
"-e",
|
||||
"json",
|
||||
"--disableInternal",
|
||||
"--disableLifeCycleHooks",
|
||||
"--disablePrivate",
|
||||
"--disableProtected",
|
||||
"-d",
|
||||
".",
|
||||
"--disableRoutesGraph"
|
||||
],
|
||||
"port": 6006
|
||||
}
|
||||
},
|
||||
@@ -152,7 +190,19 @@
|
||||
"configDir": ".storybook",
|
||||
"browserTarget": "components:build",
|
||||
"compodoc": true,
|
||||
"compodocArgs": ["-e", "json", "-d", "."],
|
||||
"compodocArgs": [
|
||||
"-p",
|
||||
"./tsconfig.json",
|
||||
"-e",
|
||||
"json",
|
||||
"--disableInternal",
|
||||
"--disableLifeCycleHooks",
|
||||
"--disablePrivate",
|
||||
"--disableProtected",
|
||||
"-d",
|
||||
".",
|
||||
"--disableRoutesGraph"
|
||||
],
|
||||
"outputDir": "storybook-static"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[](https://github.com/bitwarden/clients/actions/workflows/build-browser.yml?query=branch:master)
|
||||
[](https://github.com/bitwarden/clients/actions/workflows/build-browser.yml?query=branch:main)
|
||||
[](https://crowdin.com/project/bitwarden-browser)
|
||||
[](https://gitter.im/bitwarden/Lobby)
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
The Bitwarden browser extension is written using the Web Extension API and Angular.
|
||||
|
||||

|
||||

|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
{
|
||||
"dev_flags": {},
|
||||
"devFlags": {},
|
||||
"flags": {
|
||||
"showPasswordless": true,
|
||||
"enableCipherKeyEncryption": false,
|
||||
"accountSwitching": false
|
||||
"accountSwitching": false,
|
||||
"sdk": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
{
|
||||
"devFlags": {
|
||||
"storeSessionDecrypted": false,
|
||||
"managedEnvironment": {
|
||||
"base": "https://localhost:8080"
|
||||
}
|
||||
},
|
||||
"skipWelcomeOnInstall": true
|
||||
},
|
||||
"flags": {
|
||||
"showPasswordless": true,
|
||||
"enableCipherKeyEncryption": false,
|
||||
"accountSwitching": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"flags": {
|
||||
"enableCipherKeyEncryption": false,
|
||||
"accountSwitching": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,248 +0,0 @@
|
||||
const child = require("child_process");
|
||||
const fs = require("fs");
|
||||
|
||||
const { rimraf } = require("rimraf");
|
||||
const gulp = require("gulp");
|
||||
const gulpif = require("gulp-if");
|
||||
const jeditor = require("gulp-json-editor");
|
||||
const replace = require("gulp-replace");
|
||||
|
||||
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}`;
|
||||
}
|
||||
|
||||
async function dist(browserName, manifest) {
|
||||
const { default: zip } = await import("gulp-zip");
|
||||
const { default: filter } = await import("gulp-filter");
|
||||
|
||||
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;
|
||||
delete manifest.sandbox;
|
||||
manifest.optional_permissions = manifest.optional_permissions.filter(
|
||||
(permission) => permission !== "privacy",
|
||||
);
|
||||
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"
|
||||
: "E7C9978F6FBCE0553429185C405E61F5380BE8EB",
|
||||
"--entitlements",
|
||||
entitlementsPath,
|
||||
];
|
||||
}
|
||||
|
||||
return rimraf([buildPath + "**/*"], { glob: true })
|
||||
.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(async () => {
|
||||
const { default: filter } = await import("gulp-filter");
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
async function safariCopyBuild(source, dest) {
|
||||
const { default: filter } = await import("gulp-filter");
|
||||
|
||||
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()));
|
||||
}
|
||||
|
||||
async function ciCoverage(cb) {
|
||||
const { default: zip } = await import("gulp-zip");
|
||||
const { default: filter } = await import("gulp-filter");
|
||||
|
||||
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;
|
||||
@@ -1,18 +1,17 @@
|
||||
const { pathsToModuleNameMapper } = require("ts-jest");
|
||||
|
||||
const { compilerOptions } = require("./tsconfig");
|
||||
const { compilerOptions } = require("../../tsconfig.base");
|
||||
|
||||
const sharedConfig = require("../../libs/shared/jest.config.angular");
|
||||
|
||||
/** @type {import('jest').Config} */
|
||||
module.exports = {
|
||||
...sharedConfig,
|
||||
preset: "jest-preset-angular",
|
||||
setupFilesAfterEnv: ["<rootDir>/test.setup.ts"],
|
||||
moduleNameMapper: pathsToModuleNameMapper(
|
||||
{ "@bitwarden/common/spec": ["../../libs/common/spec"], ...(compilerOptions?.paths ?? {}) },
|
||||
{ "@bitwarden/common/spec": ["libs/common/spec"], ...(compilerOptions?.paths ?? {}) },
|
||||
{
|
||||
prefix: "<rootDir>/",
|
||||
prefix: "<rootDir>/../../",
|
||||
},
|
||||
),
|
||||
};
|
||||
|
||||
@@ -1,25 +1,35 @@
|
||||
{
|
||||
"name": "@bitwarden/browser",
|
||||
"version": "2024.2.1",
|
||||
"version": "2025.7.0",
|
||||
"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 NODE_OPTIONS=\"--max-old-space-size=8192\" webpack",
|
||||
"build:edge": "cross-env BROWSER=edge MANIFEST_VERSION=3 NODE_OPTIONS=\"--max-old-space-size=8192\" webpack",
|
||||
"build:firefox": "cross-env BROWSER=firefox NODE_OPTIONS=\"--max-old-space-size=8192\" webpack",
|
||||
"build:opera": "cross-env BROWSER=opera MANIFEST_VERSION=3 NODE_OPTIONS=\"--max-old-space-size=8192\" webpack",
|
||||
"build:safari": "cross-env BROWSER=safari NODE_OPTIONS=\"--max-old-space-size=8192\" 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 npm run build:chrome",
|
||||
"build:prod:edge": "cross-env NODE_ENV=production npm run build:edge",
|
||||
"build:prod:firefox": "cross-env NODE_ENV=production npm run build:firefox",
|
||||
"build:prod:opera": "cross-env NODE_ENV=production npm run build:opera",
|
||||
"build:prod:safari": "cross-env NODE_ENV=production npm run build:safari",
|
||||
"dist:chrome": "npm run build:prod:chrome && mkdir -p dist && ./scripts/compress.sh dist-chrome.zip",
|
||||
"dist:edge": "npm run build:prod:edge && mkdir -p dist && ./scripts/compress.sh dist-edge.zip",
|
||||
"dist:firefox": "npm run build:prod:firefox && mkdir -p dist && ./scripts/compress.sh dist-firefox.zip",
|
||||
"dist:opera": "npm run build:prod:opera && mkdir -p dist && ./scripts/compress.sh dist-opera.zip",
|
||||
"dist:safari": "npm run build:prod:safari && ./scripts/package-safari.ps1",
|
||||
"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"
|
||||
"test:watch:all": "jest --watchAll",
|
||||
"test:clearCache": "jest --clear-cache"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
/* eslint-disable no-undef */
|
||||
/* eslint-disable @typescript-eslint/no-require-imports */
|
||||
module.exports = {
|
||||
plugins: [require("tailwindcss"), require("autoprefixer"), require("postcss-nested")],
|
||||
plugins: [
|
||||
require("postcss-import"),
|
||||
require("postcss-nested"),
|
||||
require("tailwindcss"),
|
||||
require("autoprefixer"),
|
||||
],
|
||||
};
|
||||
|
||||
30
apps/browser/scripts/compress.ps1
Executable file
30
apps/browser/scripts/compress.ps1
Executable 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"
|
||||
}
|
||||
32
apps/browser/scripts/compress.sh
Executable file
32
apps/browser/scripts/compress.sh
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
####
|
||||
# Compress the build directory into a zip file.
|
||||
####
|
||||
|
||||
set -e
|
||||
set -u
|
||||
set -x
|
||||
set -o pipefail
|
||||
|
||||
FILENAME=$1
|
||||
|
||||
SCRIPT_ROOT="$(dirname "$0")"
|
||||
BUILD_DIR="$SCRIPT_ROOT/../build"
|
||||
|
||||
# Check if build directory exists
|
||||
if [ -d "$BUILD_DIR" ]; then
|
||||
cd $BUILD_DIR
|
||||
|
||||
# Create dist directory if it doesn't exist
|
||||
DIST_DIR="../dist"
|
||||
mkdir -p $DIST_DIR
|
||||
|
||||
# Remove existing dist zip file
|
||||
DIST_PATH="$DIST_DIR/$FILENAME"
|
||||
rm -f $DIST_PATH
|
||||
|
||||
# Compress build directory
|
||||
zip -r $DIST_PATH ./
|
||||
echo "Zipped $BUILD_DIR into $DIST_PATH"
|
||||
fi
|
||||
112
apps/browser/scripts/package-safari.ps1
Executable file
112
apps/browser/scripts/package-safari.ps1
Executable 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",
|
||||
"588E3F1724AE018EBA762E42279DAE85B313E3ED",
|
||||
"--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()
|
||||
}
|
||||
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
Reference in New Issue
Block a user