diff --git a/charts/prdeploy-api/values.yaml b/charts/prdeploy-api/values.yaml index fe37abb..fc6de7c 100644 --- a/charts/prdeploy-api/values.yaml +++ b/charts/prdeploy-api/values.yaml @@ -34,7 +34,7 @@ image: tag: "" nameOverride: "" -fullnameOverride: "" +fullnameOverride: "prdeploy-api" podAnnotations: {} diff --git a/charts/prdeploy-app/values.yaml b/charts/prdeploy-app/values.yaml index a0ab3a6..1b24c3c 100644 --- a/charts/prdeploy-app/values.yaml +++ b/charts/prdeploy-app/values.yaml @@ -34,7 +34,7 @@ image: tag: "" nameOverride: "" -fullnameOverride: "" +fullnameOverride: "prdeploy-app" podAnnotations: {} diff --git a/charts/prdeploy-webhooks/common.yaml b/charts/prdeploy-webhooks/common.yaml deleted file mode 100644 index 60eb221..0000000 --- a/charts/prdeploy-webhooks/common.yaml +++ /dev/null @@ -1,24 +0,0 @@ -github: - appKey: ${{ secrets.GH_PR_DEPLOY_APP_KEY }} - token: ${{ secrets.GH_PR_DEPLOY_APP_TOKEN }} - webhookSecret: ${{ secrets.GH_PR_DEPLOY_APP_WEBHOOK_SECRET }} -slack: - token: ${{ secrets.GH_PR_DEPLOY_APP_SLACK_API_TOKEN }} -jira: - username: ${{ secrets.GH_PR_DEPLOY_APP_JIRA_USERNAME }} - password: ${{ secrets.GH_PR_DEPLOY_APP_JIRA_PASSWORD }} -aws: - region: ${{ vars.CART_AWS_REGION }} - accessKeyId: "${{ vars.CART_AWS_ACCESS_KEY_ID }}" - secretAccessKey: "${{ secrets.CART_AWS_SECRET_ACCESS_KEY }}" - -ingress: - annotations: - cert-manager.io/cluster-issuer: letsencrypt - tls: - enabled: true - -global: - environment: prod - hosts: - prDeploy: prdeploy.cart.site diff --git a/charts/prdeploy-webhooks/values.yaml b/charts/prdeploy-webhooks/values.yaml index 7da8df5..f07856e 100644 --- a/charts/prdeploy-webhooks/values.yaml +++ b/charts/prdeploy-webhooks/values.yaml @@ -40,7 +40,7 @@ image: tag: "" nameOverride: "" -fullnameOverride: "" +fullnameOverride: "prdeploy-webhooks" podAnnotations: {} diff --git a/charts/prdeploy/values.yaml b/charts/prdeploy/values.yaml index bd767cc..0df9deb 100644 --- a/charts/prdeploy/values.yaml +++ b/charts/prdeploy/values.yaml @@ -10,6 +10,7 @@ global: secretName: prdeploy-tls aws: region: us-west-2 + secretPathPrefix: /prdeploy image: registry: greggbjensen serviceAccounts: diff --git a/docs/getting-started/1-github-app.md b/docs/getting-started/1-github-app.md index 4f22ab7..b5b5083 100644 --- a/docs/getting-started/1-github-app.md +++ b/docs/getting-started/1-github-app.md @@ -82,4 +82,4 @@ Workflow run 4. From the drop down, choose each repository you want to use **prdeploy** with. 5. Click **Install**. -[Next step - 2. GitHub OAuth App](getting-started/2-github-oauth-app.md) \ No newline at end of file +[Next step - 2. GitHub OAuth App](./2-github-oauth-app.md) \ No newline at end of file diff --git a/docs/getting-started/2-github-oauth-app.md b/docs/getting-started/2-github-oauth-app.md index e42e5bc..a779665 100644 --- a/docs/getting-started/2-github-oauth-app.md +++ b/docs/getting-started/2-github-oauth-app.md @@ -25,4 +25,4 @@ For authorization of the portal to view deployments, we need to create an GitHub 3. Download and select the file from `https://github.com/greggbjensen/prdeploy/blob/main/docs/assets/images/logo-128x128.png`. 4. Click **Update application**. -[Next step - 3. Slack App](getting-started/3-slack-app.md) +[Next step - 3. Slack App](./3-slack-app.md) diff --git a/docs/getting-started/3-slack-app.md b/docs/getting-started/3-slack-app.md index 799623a..7fc5fac 100644 --- a/docs/getting-started/3-slack-app.md +++ b/docs/getting-started/3-slack-app.md @@ -54,4 +54,4 @@ users:read.email 5. Click on **Allow**. 6. Copy both Webhook URLS to your notes for the **prdeloy** portal settings. -[Next step - 4. Jira Integration](getting-started/4-jira-integration.md) +[Next step - 4. Jira Integration](./4-jira-integration.md) diff --git a/docs/getting-started/4-jira-integration.md b/docs/getting-started/4-jira-integration.md index a2cdca4..9fba3b6 100644 --- a/docs/getting-started/4-jira-integration.md +++ b/docs/getting-started/4-jira-integration.md @@ -9,4 +9,4 @@ When a pull request is create the prdeploy app will check the branch name for an 6. Enter the **Label** of `prdeloy` and click **Create**. 7. Copy the API token to your notes for the **prdeloy** portal settings. -[Next step - 5. AWS Configuration](getting-started/5-aws-configuration.md) +[Next step - 5. AWS Configuration](./5-aws-configuration.md) diff --git a/docs/getting-started/5-aws-configuration.md b/docs/getting-started/5-aws-configuration.md index 5aaebb6..04b46a3 100644 --- a/docs/getting-started/5-aws-configuration.md +++ b/docs/getting-started/5-aws-configuration.md @@ -54,14 +54,16 @@ The **prdeploy** app loads external secrets, saves settings, and tracks deployme | ------------------------------------ | ----------------------------------------------------------------------- | | /prdeploy/APP_ID | ID from GitHub App. | | /prdeploy/WEBHOOK_SECRET | Webhook secret configured for GitHub App. | -| /prdeploy/gh_app_key.pem | Secret app key downloaded from GitHub App. | +| /prdeploy/gh_app_key.pem | Secret app key downloaded from GitHub App, copy and paste contents. | | /prdeploy/GitHubAuth\_\_ClientId | Client ID for GitHub OAuth App. | | /prdeploy/GitHubAuth\_\_ClientSecret | Client Secret for GitHub OAuth App. | | /prdeploy/Jwt\_\_Key | Generated JWT validation key. | | /prdeploy/Jwt\_\_TokenEncryptionKey | Generated JWT token encryption key.
Should not be the same as above. | -`NOTE:` To generate a unique encryption key, you can run the following: +`NOTE:` To generate a unique JWT and encryption key, you can run the following: ```bash node -e "console.log(require('crypto').randomBytes(256).toString('base64'));" -``` \ No newline at end of file +``` + +[Next step - 6. prdeploy portal](./6-prdeploy-portal.md) diff --git a/docs/getting-started/6-prdeploy-portal.md b/docs/getting-started/6-prdeploy-portal.md index dd69574..cbbfad0 100644 --- a/docs/getting-started/6-prdeploy-portal.md +++ b/docs/getting-started/6-prdeploy-portal.md @@ -1,55 +1,40 @@ The web portal for **prdeploy** allows you to view and manage settings and deployments. These are the installation instructions for Kubernetes. -Each repository can have it's own set of environments and services that **prdeploy** manages. Here is how to configure those settings. +## 1. Helm chart install -## AWS configuration - -1. Create the following IAM policy as `prdeploy-backend`: - -```json -{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "ssm:PutParameter", - "ssm:GetParametersByPath", - "ssm:GetParameter" - ], - "Resource": [ - "arn:aws:ssm:{{AWS_REGION}}:{{AWS_ACCOUNT_ID}}:parameter//prdeploy/*" - ] - } - ] -} +1. Install the prerequists in Kubernetes: + 1. [ingress-nginx](https://kubernetes.github.io/ingress-nginx/deploy/#quick-start) + 2. [cert-manager with letsencrypt](https://medium.com/@manojit123/lets-encrypt-certificate-using-cert-manager-on-kubernetes-http-challenge-687ce3718baf) + 3. [external-secrets](https://external-secrets.io/v0.4.3/guides-getting-started/) +2. Create a new file `prdeploy-values.yaml` and add the following content: + +```yaml +global: + ingress: + host: prdeploy.myorg.com + aws: + region: us-west-2 + serviceAccounts: + backend: + annotations: + eks.amazonaws.com/role-arn: '' + +chart-prdeploy-app: + github: + oauth: + clientId: '' ``` -2. Add the following entries as `SecureString` to AWS Parameter Store: - -| Name | Value | -| ------------------------------------ | ----------------------------------------------------------------------- | -| /prdeploy/APP_ID | ID from GitHub App. | -| /prdeploy/WEBHOOK_SECRET | Webhook secret configured for GitHub App. | -| /prdeploy/gh_app_key.pem | Secret app key downloaded from GitHub App. | -| /prdeploy/GitHubAuth\_\_ClientId | Client ID for GitHub OAuth App. | -| /prdeploy/GitHubAuth\_\_ClientSecret | Client Secret for GitHub OAuth App. | -| /prdeploy/Jwt\_\_Key | Generated JWT validation key. | -| /prdeploy/Jwt\_\_TokenEncryptionKey | Generated JWT token encryption key.
Should not be the same as above. | - -`NOTE:` To generate a unique encryption key, you can run the following: +2. Run the following command with helm: ```bash -node -e "console.log(require('crypto').randomBytes(256).toString('base64'));" +helm upgrade prdeploy oci://registry-1.docker.io/greggbjensen/prdeploy \ + --install --reset-values --force --create-namespace -n prdeploy \ + -f ./prdeploy-values.yaml ``` -## Helm chart install -1. Install the prerequists in Kubernetes: - - 1. ingress-nginx - 2. cert-manager with letsencrypt - 3. External secrets +## 2. Settings _NOTE: For effeciency settings cache only updates every 5 minutes._ @@ -66,3 +51,5 @@ node -e "console.log(require('crypto').randomBytes(256).toString('base64'));" 5. Go to **Settings** and **General** for your repository and check `Always suggest updating pull request branches` to get the pull request **Update** button. 1. This makes it much easier to update your pull requests to latest before deploying. + +[Next step - 7. GitHub Actions](./7-github-actions.md) diff --git a/docs/getting-started/overview.md b/docs/getting-started/overview.md index e7bd7e4..4290e6e 100644 --- a/docs/getting-started/overview.md +++ b/docs/getting-started/overview.md @@ -2,8 +2,10 @@ Here is how to get started by configuring your GitHub organization with a GitHub ## Setup steps -1. [GitHub App](1-github-app.md) - Webhooks for responding to GitHub events. -2. [GitHub OAuth App](2-github-oauth-app.md) - Authentication for accessing deployment portal. -3. [Slack App](3-slack-app.md) - Post notifications for deployments and releases. -4. [Repo config](4-repo-config.md) - Configure your repository with environments and services. -5. [GitHub Actions](5-github-actions.md) - A combined deploy that intuitively promotes services in a single workflow. +1. [GitHub App](./1-github-app.md) - Webhooks for responding to GitHub events. +2. [GitHub OAuth App](./2-github-oauth-app.md) - Authentication for accessing deployment portal. +3. [Slack App](./3-slack-app.md) - Post notifications for deployments and releases. +4. [Repo config](./4-jira-integration.md) - Configure your repository with environments and services. +5. [AWS Configuration](./5-aws-configuration.md) - External secrets, save settings, and track deployment versions through AWS parameter store. +6. [prdeploy portal](./6-prdeploy-portal.md) - The web portal that allows you to view and manage settings and deployments. +7. [GitHub Actions](./7-github-actions.md) - A combined deploy that intuitively promotes services in a single workflow. diff --git a/prdeploy-app/src/app/settings/environment-form/add-exclude-rollback-service-dialog/add-exclude-rollback-service-dialog.component.html b/prdeploy-app/src/app/settings/environment-form/add-exclude-rollback-service-dialog/add-exclude-rollback-service-dialog.component.html new file mode 100644 index 0000000..213bdc3 --- /dev/null +++ b/prdeploy-app/src/app/settings/environment-form/add-exclude-rollback-service-dialog/add-exclude-rollback-service-dialog.component.html @@ -0,0 +1,25 @@ + +
+
+
Name
+
+ +
+
+ +
+ + +
+
+
diff --git a/prdeploy-app/src/app/settings/environment-form/add-exclude-rollback-service-dialog/add-exclude-rollback-service-dialog.component.scss b/prdeploy-app/src/app/settings/environment-form/add-exclude-rollback-service-dialog/add-exclude-rollback-service-dialog.component.scss new file mode 100644 index 0000000..f699f5b --- /dev/null +++ b/prdeploy-app/src/app/settings/environment-form/add-exclude-rollback-service-dialog/add-exclude-rollback-service-dialog.component.scss @@ -0,0 +1,25 @@ +.actions { + margin-top: 30px; + display: flex; + margin-left: auto; + + dx-button { + margin-left: 15px; + } +} + +.form { + display: flex; + flex-direction: column; +} + +.dx-field { + + .dx-field-label { + width: 30%; + } + + .dx-field-value { + width: 70%; + } +} diff --git a/prdeploy-app/src/app/settings/environment-form/add-exclude-rollback-service-dialog/add-exclude-rollback-service-dialog.component.ts b/prdeploy-app/src/app/settings/environment-form/add-exclude-rollback-service-dialog/add-exclude-rollback-service-dialog.component.ts new file mode 100644 index 0000000..f41cb01 --- /dev/null +++ b/prdeploy-app/src/app/settings/environment-form/add-exclude-rollback-service-dialog/add-exclude-rollback-service-dialog.component.ts @@ -0,0 +1,53 @@ +import { ChangeDetectorRef, Component, EventEmitter, Input, Output } from '@angular/core'; +import { DxButtonModule, DxPopupModule, DxTextBoxModule } from 'devextreme-angular'; + +@Component({ + selector: 'app-add-exclude-rollback-service-dialog', + standalone: true, + imports: [DxPopupModule, DxButtonModule, DxTextBoxModule], + templateUrl: './add-exclude-rollback-service-dialog.component.html', + styleUrl: './add-exclude-rollback-service-dialog.component.scss' +}) +export class AddExcludeRollbackServiceDialogComponent { + @Output() visibleChange = new EventEmitter(); + @Output() addInput = new EventEmitter(); + + name = ''; + + private _visible = false; + + get visible() { + return this._visible; + } + + @Input() + set visible(value: boolean) { + this._visible = value; + this.clearFields(); + } + + constructor(private _changeDetectorRef: ChangeDetectorRef) {} + + clearFields() { + this.name = ''; + } + + onVisibleChange(): void { + this.visibleChange.emit(this.visible); + } + + add(): void { + if (!this.name) { + return; + } + + this.addInput.emit(this.name); + this.visible = false; + this._changeDetectorRef.detectChanges(); + } + + cancel(): void { + this.visible = false; + this._changeDetectorRef.detectChanges(); + } +} diff --git a/prdeploy-app/src/app/settings/environment-form/environment-form.component.html b/prdeploy-app/src/app/settings/environment-form/environment-form.component.html index ce9db92..b2a04df 100644 --- a/prdeploy-app/src/app/settings/environment-form/environment-form.component.html +++ b/prdeploy-app/src/app/settings/environment-form/environment-form.component.html @@ -31,6 +31,30 @@

General

+
+ Exclude from rollback + +
+ @for (item of environment.excludeFromRollback; track item) { +
+ +
+ +
+
+ }
@@ -47,11 +71,11 @@

Automation Test

-
+
- Workflow Inputs: + Workflow inputs Automation Test + + diff --git a/prdeploy-app/src/app/settings/environment-form/environment-form.component.scss b/prdeploy-app/src/app/settings/environment-form/environment-form.component.scss index 2639b4f..3530fcf 100644 --- a/prdeploy-app/src/app/settings/environment-form/environment-form.component.scss +++ b/prdeploy-app/src/app/settings/environment-form/environment-form.component.scss @@ -5,7 +5,7 @@ width: 100%; } -.environment-settings .test-workflow-inputs { +.environment-settings .add-items { margin-top: 20px; display: block; margin-left: 10px; @@ -14,14 +14,28 @@ margin-left: 15px; } } -.add-workflow-input-btn { + +.add-item-input-btn { margin-left: 22px; + + &.exclude-rollback { + margin-left: 0; + } } .field-removable { display: flex; } +.exclude-rollback-field { + margin-top: 5px; + + label { + margin-left: 165px; + width: 145px; + } +} + .field-group-title { font-weight: normal; border-bottom: solid 1px $border-color; diff --git a/prdeploy-app/src/app/settings/environment-form/environment-form.component.ts b/prdeploy-app/src/app/settings/environment-form/environment-form.component.ts index 01ac164..00ceee0 100644 --- a/prdeploy-app/src/app/settings/environment-form/environment-form.component.ts +++ b/prdeploy-app/src/app/settings/environment-form/environment-form.component.ts @@ -5,6 +5,7 @@ import { KeyValuePipe } from '@angular/common'; import { ValueChangedEvent } from 'devextreme/ui/text_box'; import { SettingsLevel } from '../models'; import { AddAutomationInputDialogComponent } from './add-automation-input-dialog/add-automation-input-dialog.component'; +import { AddExcludeRollbackServiceDialogComponent } from './add-exclude-rollback-service-dialog/add-exclude-rollback-service-dialog.component'; @Component({ selector: 'app-environment-form', @@ -15,6 +16,7 @@ import { AddAutomationInputDialogComponent } from './add-automation-input-dialog DxCheckBoxModule, DxButtonModule, AddAutomationInputDialogComponent, + AddExcludeRollbackServiceDialogComponent, KeyValuePipe ], templateUrl: './environment-form.component.html', @@ -38,6 +40,26 @@ export class EnvironmentFormComponent { } addAutomationInputVisible = false; + addExcludeRollbackServiceVisible = false; + + showAddExcludeRollbackService() { + this.addExcludeRollbackServiceVisible = true; + } + + addExcludeRollbackService(name: string) { + if (!this.environment.excludeFromRollback) { + this.environment.excludeFromRollback = []; + } + + if (!this.environment.excludeFromRollback.find(e => e.toLocaleLowerCase() === name.toLowerCase())) { + this.environment.excludeFromRollback.push(name); + } + } + + removeExcludeRollbackService(name: any) { + const index = this.environment.excludeFromRollback.indexOf(name); + this.environment.excludeFromRollback.splice(index, 1); + } showAddAutomationInput() { this.addAutomationInputVisible = true;