generated from Szandor72/devops-center-template
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #60 from Szandor72/staging
Staging DevOps Center Changes
- Loading branch information
Showing
55 changed files
with
18,248 additions
and
18,313 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
force-app/main/default/classes/AccountService.cls | ||
force-app/main/default/classes/AccountService.cls-meta.xml |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
name: Code Scans with SFDX Scanner | ||
|
||
on: | ||
pull_request: | ||
types: [opened, synchronize, reopened] | ||
branches: | ||
- integration | ||
paths: | ||
- 'force-app/**' | ||
|
||
jobs: | ||
sfdx-scanner: | ||
name: 'Validate Code' | ||
uses: 'Szandor72/devops-center-actions/.github/workflows/validate-code.yml@main' | ||
secrets: inherit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
name: Validate Deployment | ||
|
||
on: | ||
pull_request: | ||
types: [opened, synchronize, reopened] | ||
branches: | ||
- integration | ||
paths: | ||
- 'force-app/**' | ||
|
||
jobs: | ||
validate-deployment: | ||
name: 'SFDX Scanner' | ||
uses: 'Szandor72/devops-center-actions/.github/workflows/validate-deployment.yml@main' | ||
secrets: inherit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
name: Custom Metadata Checks | ||
|
||
on: | ||
pull_request: | ||
types: [opened, synchronize, reopened] | ||
branches: | ||
- integration | ||
paths: | ||
- 'force-app/**' | ||
|
||
jobs: | ||
validate-metadata: | ||
name: 'Validate Metadata' | ||
uses: 'Szandor72/devops-center-actions/.github/workflows/validate-metadata.yml@main' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,110 @@ | ||
# Salesforce DX Project: Next Steps | ||
# Salesforce DevOps Center Demo Project | ||
|
||
Now that you’ve created a Salesforce DX project, what’s next? Here are some documentation resources | ||
to get you started. | ||
## What is this? | ||
|
||
## How Do You Plan to Deploy Your Changes? | ||
This Demo Project has 3 dimensions: | ||
|
||
Do you want to deploy a set of changes, or create a self-contained application? Choose a | ||
[development model](https://developer.salesforce.com/tools/vscode/en/user-guide/development-models). | ||
1. It is a sample project to demonstrate how Salesforce DevOps Center can be used together with | ||
re-usable GitHub Actions and additional Salesforce tools to build a **loosely coupled **CI** | ||
pipeline** with automated Quality Gates. | ||
2. It acknowledges projects contain **legacy** (read: older, bad quality) **metadata** which should be scanned and reported but not block or confuse new development | ||
3. It shows that **App Builders don't need to use VS Code**, or any IDE, or the Command Line to get the same benefits as Developers do. | ||
|
||
## Configure Your Salesforce DX Project | ||
## Loosely coupled how? | ||
|
||
The `sfdx-project.json` file contains useful configuration information for your project. See | ||
[Salesforce DX Project Configuration](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_ws_config.htm) | ||
in the _Salesforce DX Developer Guide_ for details about this file. | ||
Imagine for a moment, you have created - over time - a dozen Salesforce projects, each with their | ||
own CI yml files, ignore files, and so on. Now imagine you want to make a change to all of them. You | ||
could go through each repository and make the change, but that's a lot of work. Instead, you could | ||
make a change in one place, and have all of your projects automatically use the updated version. | ||
|
||
## Read All About It | ||
## What are common moving parts that need loose coupling? | ||
|
||
- [Salesforce Extensions Documentation](https://developer.salesforce.com/tools/vscode/) | ||
- [Salesforce CLI Setup Guide](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_intro.htm) | ||
- [Salesforce DX Developer Guide](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_intro.htm) | ||
- [Salesforce CLI Command Reference](https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference.htm) | ||
A Salesforce Project is tooling-wise a web development/JavaScript project with very few extra bells | ||
and whistles. The default DX Project setup relies on a node `package.json` for tooling like ESLint, | ||
Jest, or Prettier. Each tools comes with its own config and rule files as well as ignore file | ||
options. | ||
|
||
Then you have your actual CI worfklow configuration file(s) which have dependencies to the SF CLI, | ||
Orgs and Authentication, Caching, and additional tools like PMD or the SFDX Scanner plugin. | ||
|
||
These tools come with config and rulesets of their own. | ||
|
||
## What will it do? | ||
|
||
All [checks](https://github.com/Szandor72/devops-center-demo/actions) run on **Pull Request** | ||
against `integration` branch for changes in the `force-app` folder. | ||
|
||
An integration sandbox is supposed to be the target org. | ||
|
||
Three workflows are configured: | ||
|
||
- **validate-metadata** | ||
|
||
- SFDX Scanner with PMD engine and custom rules for | ||
- sObjects | ||
- Flows | ||
- Misc Metadata | ||
- only new/modified files will be prettified (3rd Party Action) | ||
|
||
- **validate-code** | ||
|
||
- Jest Tests | ||
- SFDX Scanner | ||
- all modified files will be checked whether they have a match in | ||
`.ci/legacy-metadata-files.txt` | ||
- for modified legacy files | ||
- only code will be scanned | ||
- the build will never fail if issues are found | ||
- Issues are reported in markdown table as step summary as well as | ||
- CSV upload to a target org (get a notification in the org optionally) | ||
- CSV upload is only triggered if new issues are detected upon re-rerun of a scan per | ||
PR | ||
- for all other files (new and modified) | ||
- strict code scans are performed | ||
|
||
- **validate-deployment** | ||
|
||
- runs a test deployment against integration sandbox and runs all local tests | ||
|
||
## How does it work? | ||
|
||
There are several repositories involved: | ||
|
||
- https://github.com/Szandor72/devops-center-template | ||
- an empty DX project with no config files. Use this as starting point in DevOps Center or | ||
create your own fork | ||
- https://github.com/Szandor72/devops-center-demo | ||
- a copy of the template with a bit of Salesforce Metadata and all | ||
[Actions configured](https://github.com/Szandor72/devops-center-demo/actions) and minimal | ||
[workflow files](https://github.com/Szandor72/devops-center-demo/tree/main/.github/workflows). | ||
All secrets for authentication are stored here and passed on to: | ||
- https://github.com/Szandor72/devops-center-actions | ||
- this repository stores all the GitHub Actions that are used in the demo project. It can | ||
"inherit" secrets from the Demo Repo because GitHub Actions can access secrets from the same | ||
GitHub organization. | ||
- https://github.com/Szandor72/devops-center-local-config-files | ||
- is [a npm package ](https://www.npmjs.com/package/devops-center-local-config-files) which | ||
contains all the config files as well as (exemplary, strict, custom) PMD | ||
[rulesets](https://github.com/Szandor72/devops-center-local-config-files/tree/main/pmd-rulesets) | ||
for various metadata types and code. | ||
- The config files and rulesets are intended to be copied and used only during build time by | ||
the GitHub Actions Workflows. | ||
- If you run **`npm install` locally**, the files will be copied as well. If you commit your | ||
copies, these files will be used instead of the ones from the npm package. | ||
- The npm package also provides a few | ||
[JavaScript files](https://github.com/Szandor72/devops-center-local-config-files/tree/main/ci-scripts) | ||
that help preparing scans and parsing scan results by generating GitHub Annotations and | ||
summary tables. | ||
|
||
## How can I use it? | ||
|
||
- Create a fork of the template repository and use it as starting point in DevOps Center | ||
- Make sure to activate Actions, those aren't enabled by default when forking | ||
- Configure the Actions to use your own Orgs and Secrets | ||
- `${{ secrets.INTEGRATION_SANDBOX_SFDX_URL}}` will be used to do test deployments and CSV Scan Report File Upload | ||
- GitHub Action workflows are configured to run when a PR against `integration` branch is opened | ||
- Please make sure the `integration` branch exists | ||
|
||
## Todos | ||
|
||
- figure out how to cache yarn plugins (SFDX Scanner) or wait for Scanner GH Action to be released |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
/** | ||
* AccountService Class | ||
* Provides various services related to Account object | ||
*/ | ||
public class AccountService { | ||
/** | ||
* Fetches details for a given account | ||
* @param accountId The ID of the account | ||
* @return Account The details of the account | ||
*/ | ||
public Account getAccDetails(Id accountId) { | ||
// SOQL query inside a loop - bad practice | ||
for (Id accId : new List<Id>{ accountId }) { | ||
Account acc = [SELECT Id, Name, Industry FROM Account WHERE Id = :accId]; | ||
return acc; | ||
} | ||
return null; | ||
} | ||
|
||
public Account getAccDetails2(Id accountId) { | ||
// SOQL query inside a loop - bad practice | ||
for (Id accId : new List<Id>{ accountId }) { | ||
Account acc = [SELECT Id, Name, Industry FROM Account WHERE Id = :accId]; | ||
update acc; | ||
return acc; | ||
} | ||
return null; | ||
} | ||
|
||
// This method lacks ApexDocs | ||
public void UpdateAccount(List<Account> accounts) { | ||
// DML operation inside a loop - bad practice | ||
for (Account acc : accounts) { | ||
acc.Name += ' - Updated'; | ||
update acc; // This should be done in bulk outside the loop | ||
} | ||
} | ||
|
||
/** | ||
* Deletes a specified account | ||
* @param accountId The ID of the account to be deleted | ||
*/ | ||
public void delete_Account(Id accountId) { | ||
// Hardcoding IDs - bad practice | ||
Id hardCodedId = '001xx000003DGAXAA4'; | ||
delete [SELECT Id FROM Account WHERE Id = :hardCodedId]; | ||
} | ||
|
||
// This method lacks ApexDocs | ||
public List<Account> ListAccounts() { | ||
// Not using bulkified approach - bad practice | ||
List<Account> accounts = [SELECT Id, Name FROM Account LIMIT 1]; | ||
return accounts; | ||
} | ||
|
||
/** | ||
* Calculates the annual revenue | ||
* - This ApexDoc is incomplete and lacks parameter description | ||
* @return Decimal The calculated annual revenue | ||
*/ | ||
public String CalculateAnnualRevenue() { | ||
// Lack of null checks and exception handling - bad practice | ||
Account acc = [SELECT Industry FROM Account WHERE Id = '001xx000003DGAZAA4']; | ||
return acc.Industry; | ||
} | ||
|
||
// This method lacks ApexDocs | ||
public List<Account> ListAccounts2() { | ||
// Not using bulkified approach - bad practice | ||
List<Account> accounts = [SELECT Id, Name FROM Account LIMIT 1]; | ||
return accounts; | ||
} | ||
|
||
// This method lacks ApexDocs | ||
public List<Account> ListAccounts3() { | ||
// Not using bulkified approach - bad practice | ||
List<Account> accounts = [SELECT Id, Name FROM Account LIMIT 1]; | ||
return accounts; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?xml version="1.0" encoding="UTF-8" ?> | ||
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata"> | ||
<apiVersion>59.0</apiVersion> | ||
<status>Active</status> | ||
</ApexClass> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/* | ||
* @description service related updates | ||
*/ | ||
public with sharing class CaseService { | ||
public static void doUpdates(Set<Id> caseIds) { | ||
List<Case> cases = [SELECT Id, Status FROM Case WHERE Id IN :caseIds]; | ||
for (Case c : cases) { | ||
c.Status = 'Closed'; | ||
// raise pmd error | ||
update c; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?xml version="1.0" encoding="UTF-8" ?> | ||
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata"> | ||
<apiVersion>58.0</apiVersion> | ||
<status>Active</status> | ||
</ApexClass> |
68 changes: 68 additions & 0 deletions
68
force-app/main/default/classes/ContentDocumentTriggerHandler.cls
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/** | ||
* @description Handles legacy metadata scan file uploads from GitHub | ||
*/ | ||
public with sharing class ContentDocumentTriggerHandler { | ||
/** | ||
* @description sends a notification for legacy scan file uploads | ||
* @param newContentDocumentMap - received from trigger | ||
*/ | ||
@SuppressWarnings('PMD.ApexCRUDViolation') | ||
public static void notifyOnLegacyCodeScanFileUploads( | ||
Map<Id, ContentDocument> newContentDocumentMap | ||
) { | ||
Boolean isBulkOperation = newContentDocumentMap.values().size() > 1; | ||
if (isBulkOperation) { | ||
return; | ||
} | ||
List<CustomNotificationType> notificationTypes = [ | ||
SELECT Id, DeveloperName | ||
FROM CustomNotificationType | ||
WHERE DeveloperName = 'NewMetadataScanAvailable' | ||
]; | ||
if (notificationTypes.isEmpty()) { | ||
return; | ||
} | ||
CustomNotificationType notificationType = notificationTypes[0]; | ||
for ( | ||
ContentDocument matchingFile : filterContentDocuments(newContentDocumentMap.values()) | ||
) { | ||
Messaging.CustomNotification notification = new Messaging.CustomNotification(); | ||
|
||
notification.setTitle('New Metadata Scan Available'); | ||
notification.setBody( | ||
'Please review the scan and discuss necessary changes with the developer' | ||
); | ||
|
||
notification.setNotificationTypeId(notificationType.Id); | ||
notification.setTargetId(matchingFile.Id); | ||
|
||
// TODO identify targets for notification, i.e. public group's first level members? | ||
// uploading user should be a technical user | ||
try { | ||
notification.send(new Set<String>{ UserInfo.getUserId() }); | ||
} catch (Exception e) { | ||
return; | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* @description Filter ContentDocument sobjects by file extension and title | ||
* @param contentDocuments list of ContentDocument sobjects to filter | ||
* @return matchingContentDocuments | ||
*/ | ||
public static List<ContentDocument> filterContentDocuments( | ||
List<ContentDocument> contentDocuments | ||
) { | ||
List<ContentDocument> matchingContentDocuments = new List<ContentDocument>(); | ||
for (ContentDocument uploadedFile : contentDocuments) { | ||
if ( | ||
String.isNotBlank(uploadedFile.Title) && | ||
uploadedFile.Title.contains('legacy-scan-results_') | ||
) { | ||
matchingContentDocuments.add(uploadedFile); | ||
} | ||
} | ||
return matchingContentDocuments; | ||
} | ||
} |
5 changes: 5 additions & 0 deletions
5
force-app/main/default/classes/ContentDocumentTriggerHandler.cls-meta.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?xml version="1.0" encoding="UTF-8" ?> | ||
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata"> | ||
<apiVersion>58.0</apiVersion> | ||
<status>Active</status> | ||
</ApexClass> |
Oops, something went wrong.