Skip to content

Commit

Permalink
Added pipeline for GitHub Actions
Browse files Browse the repository at this point in the history
  • Loading branch information
jongpie committed Feb 27, 2023
1 parent 104a41c commit 9c3ef74
Show file tree
Hide file tree
Showing 10 changed files with 9,320 additions and 1,746 deletions.
276 changes: 276 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
# Pipeline for Nebula Cache Manager
name: Build

on:
push:
branches:
- main
paths-ignore:
- 'content/**'
- 'docs/**'
- 'examples/**'
- 'packages/**'
- '.forceignore'
- '.gitignore'
- '.prettierignore'
- '.prettierrc'
- 'CONTRIBUTING.md'
- 'LICENSE'
- 'package.json'
- 'README.md'
- './**/README.md'
- 'sfdx-project.json'
pull_request:
types: [opened, synchronize, reopened]
paths-ignore:
- 'content/**'
- 'docs/**'
- 'examples/**'
- 'packages/**'
- '.forceignore'
- '.gitignore'
- '.prettierignore'
- '.prettierrc'
- 'CONTRIBUTING.md'
- 'LICENSE'
- 'package.json'
- 'README.md'
- './**/README.md'
- 'sfdx-project.json'

jobs:
code-quality-tests:
name: 'Run Code Quality Tests'
runs-on: ubuntu-latest
steps:
- name: 'Checkout source code'
uses: actions/checkout@v3

- name: 'Restore node_modules cache'
id: cache-npm
uses: actions/cache@v3
with:
path: node_modules
key: npm-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
npm-${{ env.cache-name }}-
npm-
- name: 'Install npm dependencies'
if: steps.cache-npm.outputs.cache-hit != 'true'
run: npm ci

- name: 'Verify Apex with SFDX Scanner'
run: |
npm run sfdx:plugins:link:scanner
npm run scan:apex
- name: 'Verify formatting with Prettier'
run: npm run prettier:verify

base-scratch-org-tests:
name: 'Run Base Scratch Org Tests'
needs: [code-quality-tests]
runs-on: ubuntu-latest
environment: 'Base Scratch Org'
steps:
- name: 'Checkout source code'
uses: actions/checkout@v3

- name: 'Restore node_modules cache'
id: cache-npm
uses: actions/cache@v3
with:
path: node_modules
key: npm-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
npm-${{ env.cache-name }}-
npm-
- name: 'Install npm dependencies'
if: steps.cache-npm.outputs.cache-hit != 'true'
run: npm ci

- name: 'Authorize Dev Hub'
shell: bash
run: |
echo "${{ env.DEV_HUB_JWT_SERVER_KEY }}" > ./jwt-server.key
npx sfdx force:auth:jwt:grant --instanceurl ${{ env.DEV_HUB_AUTH_URL }} --clientid ${{ env.DEV_HUB_CONSUMER_KEY }} --username ${{ env.DEV_HUB_BOT_USERNAME }} --jwtkeyfile ./jwt-server.key --setdefaultdevhubusername
env:
DEV_HUB_AUTH_URL: ${{ secrets.DEV_HUB_AUTH_URL }}
DEV_HUB_BOT_USERNAME: ${{ secrets.DEV_HUB_BOT_USERNAME }}
DEV_HUB_CONSUMER_KEY: ${{ secrets.DEV_HUB_CONSUMER_KEY }}
DEV_HUB_JWT_SERVER_KEY: ${{ secrets.DEV_HUB_JWT_SERVER_KEY }}

- name: 'Create Base Scratch Org'
run: npx sfdx force:org:create --durationdays 1 --definitionfile ./config/scratch-orgs/base-scratch-def.json --wait 20 --setdefaultusername --json

- name: 'Deploy Source to Scratch Org'
run: npx sfdx force:source:deploy --sourcepath ./nebula-cache-manager/

- name: 'Assign Cache Manager Admin Permission Set'
run: npm run permset:assign:admin

# Nebula Cache Manager has functionality that use the session partition of platform cache, which only works when the current user has an active session.
# The code should work with or without an active session, so the pipeline runs the tests twice - asynchronously and synchronously.
# Running the Apex tests sync & async serves as an extra level of integration testing to ensure that everything works with or without an active session.
- name: 'Run Apex Tests Asynchronously'
run: npm run test:apex:nocoverage

- name: 'Run Apex Tests Synchronously'
run: npm run test:apex:nocoverage -- --synchronous

- name: 'Delete Base Scratch Org'
run: npx sfdx force:org:delete --json --noprompt
if: ${{ always() }}

platform-cache-scratch-org-tests:
name: 'Run Platform Cache Scratch Org Tests'
needs: [code-quality-tests]
runs-on: ubuntu-latest
environment: 'Platform Cache Scratch Org'
steps:
- name: 'Checkout source code'
uses: actions/checkout@v3

- name: 'Restore node_modules cache'
id: cache-npm
uses: actions/cache@v3
with:
path: node_modules
key: npm-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
npm-${{ env.cache-name }}-
npm-
- name: 'Install npm dependencies'
if: steps.cache-npm.outputs.cache-hit != 'true'
run: npm ci

- name: 'Authorize Dev Hub'
shell: bash
run: |
echo "${{ env.DEV_HUB_JWT_SERVER_KEY }}" > ./jwt-server.key
npx sfdx force:auth:jwt:grant --instanceurl ${{ env.DEV_HUB_AUTH_URL }} --clientid ${{ env.DEV_HUB_CONSUMER_KEY }} --username ${{ env.DEV_HUB_BOT_USERNAME }} --jwtkeyfile ./jwt-server.key --setdefaultdevhubusername
env:
DEV_HUB_AUTH_URL: ${{ secrets.DEV_HUB_AUTH_URL }}
DEV_HUB_BOT_USERNAME: ${{ secrets.DEV_HUB_BOT_USERNAME }}
DEV_HUB_CONSUMER_KEY: ${{ secrets.DEV_HUB_CONSUMER_KEY }}
DEV_HUB_JWT_SERVER_KEY: ${{ secrets.DEV_HUB_JWT_SERVER_KEY }}

- name: 'Create Platform Cache Scratch Org'
run: npx sfdx force:org:create --durationdays 1 --definitionfile ./config/scratch-orgs/platform-cache-scratch-def.json --wait 20 --setdefaultusername --json

- name: 'Deploy Source to Scratch Org'
run: npx sfdx force:source:deploy --sourcepath ./nebula-cache-manager/

- name: 'Assign Cache Manager Admin Permission Set'
run: npm run permset:assign:admin

# Nebula Cache Manager has functionality that use the session partition of platform cache, which only works when the current user has an active session.
# The code should work with or without an active session, so the pipeline runs the tests twice - asynchronously and synchronously.
# Running the Apex tests sync & async serves as an extra level of integration testing to ensure that everything works with or without an active session.
- name: 'Run Apex Tests Asynchronously'
run: npm run test:apex:nocoverage

- name: 'Run Apex Tests Synchronously'
run: npm run test:apex -- --synchronous

- name: 'Upload Apex test code coverage to Codecov.io'
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
flags: Apex

- name: 'Delete Platform Cache Scratch Org'
run: npx sfdx force:org:delete --json --noprompt
if: ${{ always() }}

create-unlocked-package-versions:
name: 'Create Package Versions'
needs: [base-scratch-org-tests, platform-cache-scratch-org-tests]
if: ${{ github.ref != 'refs/heads/main' }}
runs-on: ubuntu-latest
outputs:
noNamespacePackageVersionId: ${{ steps.createNoNamespace.outputs.noNamespacePackageVersionId }}
withNamespacePackageVersionId: ${{ steps.createWithNamespace.outputs.withNamespacePackageVersionId }}
steps:
- name: 'Checkout source code'
uses: actions/checkout@v3

- name: 'Restore node_modules cache'
id: cache-npm
uses: actions/cache@v3
with:
path: node_modules
key: npm-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
npm-${{ env.cache-name }}-
npm-
- name: Set environment variables
run: |
echo "SFDX_DISABLE_AUTOUPDATE=true" >> $GITHUB_ENV
echo "SFDX_DISABLE_SOURCE_MEMBER_POLLING=true" >> $GITHUB_ENV
echo "SFDX_DISABLE_TELEMETRY=true" >> $GITHUB_ENV
echo "SFDX_PROJECT_AUTOUPDATE_DISABLE_FOR_PACKAGE_VERSION_CREATE=true" >> $GITHUB_ENV
- name: 'Install npm dependencies'
if: steps.cache-npm.outputs.cache-hit != 'true'
run: npm ci

- name: 'Authorize Dev Hub'
shell: bash
run: |
echo "${{ env.DEV_HUB_JWT_SERVER_KEY }}" > ./jwt-server.key
npx sfdx force:auth:jwt:grant --instanceurl ${{ env.DEV_HUB_AUTH_URL }} --clientid ${{ env.DEV_HUB_CONSUMER_KEY }} --username ${{ env.DEV_HUB_BOT_USERNAME }} --jwtkeyfile ./jwt-server.key --setdefaultdevhubusername
rm ./jwt-server.key
env:
DEV_HUB_AUTH_URL: ${{ secrets.DEV_HUB_AUTH_URL }}
DEV_HUB_BOT_USERNAME: ${{ secrets.DEV_HUB_BOT_USERNAME }}
DEV_HUB_CONSUMER_KEY: ${{ secrets.DEV_HUB_CONSUMER_KEY }}
DEV_HUB_JWT_SERVER_KEY: ${{ secrets.DEV_HUB_JWT_SERVER_KEY }}

- name: 'Create no-namespace package version'
id: createNoNamespace
run: npm run package:version:create:nonamespace -- --branch "${{ inputs.branch }}" --tag ${{ github.sha }}

- name: 'Create namespaced package version'
id: createWithNamespace
run: npm run package:version:create:withnamespace -- --branch "${{ inputs.branch }}" --tag ${{ github.sha }}

# run: |
# noNamespacePackageVersionId=$(npm run package:version:create:nonamespace -- --branch "${{ inputs.branch }}" --tag ${{ github.sha }} | jq -e -r ".result.SubscriberPackageVersionId")
# echo "noNamespacePackageVersionId=$noNamespacePackageVersionId" >> $GITHUB_ENV
# echo "noNamespacePackageVersionId=$noNamespacePackageVersionId" >> $GITHUB_OUTPUT

# - name: 'Create namespaced package version'
# id: createWithNamespace
# run: |
# withNamespacePackageVersionId=$(npm run package:version:create:nonamespace -- --branch "${{ inputs.branch }}" --tag ${{ github.sha }} | jq -e -r ".result.SubscriberPackageVersionId")
# echo "withNamespacePackageVersionId=$withNamespacePackageVersionId" >> $GITHUB_ENV
# echo "withNamespacePackageVersionId=$withNamespacePackageVersionId" >> $GITHUB_OUTPUT

# - name: 'Create Platform Cache Scratch Org'
# run: npx sfdx force:org:create -f config/scratch-orgs/platform-cache-scratch-def.json -a scratch-org -s -d 1

# - name: 'Install no-namespace package version'
# run: npx sfdx force:package:install -p ${{ env.noNamespacePackageVersionId }} -u scratch-org -w 10

# - name: 'Install namespaced package version'
# run: npx sfdx force:package:install -p ${{ env.withNamespacePackageVersionId }} -u scratch-org -w 10

# - name: 'Delete Platform Cache Scratch Org'
# run: npx sfdx force:org:delete --json --noprompt
# if: ${{ always() }}

- name: 'Commit New Package Versions'
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action Bot"
npm run sfdx:plugins:link:bummer
npx sfdx bummer:package:aliases:sort
npx prettier --write ./sfdx-project.json
git add ./sfdx-project.json
git commit -m "Created new package versions"
git push
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ A flexible cache management system for Salesforce Apex developers. Built to be s

Learn more about the history & implementation of this repo in [the Joys of Apex article 'Iteratively Building a Flexible Caching System for Apex'](https://www.jamessimone.net/blog/joys-of-apex/iteratively-building-a-flexible-caching-system/)

## Unlocked Package - `Nebula` Namespace - v1.0.1
## Unlocked Package - `Nebula` Namespace - v1.0.2

[![Install Unlocked Package (Nebula namespace) in a Sandbox](./images/btn-install-unlocked-package-sandbox.png)](https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015n6rQAA)
[![Install Unlocked Package (Nebula namespace) in Production](./images/btn-install-unlocked-package-production.png)](https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015n6rQAA)

## Unlocked Package - No Namespace - v1.0.1
## Unlocked Package - No Namespace - v1.0.2

[![Install Unlocked Package (no namespace) in a Sandbox](./images/btn-install-unlocked-package-sandbox.png)](https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015n6hQAA)
[![Install Unlocked Package (no namespace) in Production](./images/btn-install-unlocked-package-production.png)](https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015n6hQAA)
Expand Down
2 changes: 1 addition & 1 deletion config/scratch-orgs/base-scratch-def.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"features": [],
"settings": {
"securitySettings": {
"enableAdminLoginAsAnyUser": false
"enableAdminLoginAsAnyUser": true
},
"userManagementSettings": {
"enableEnhancedPermsetMgmt": true,
Expand Down
4 changes: 2 additions & 2 deletions config/scratch-orgs/platform-cache-scratch-def.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"orgName": "Nebula Cache Manager - Base Scratch Org",
"orgName": "Nebula Cache Manager - Platform Cache Scratch Org",
"edition": "Enterprise",
"hasSampleData": true,
"country": "US",
"language": "en_US",
"features": ["PlatformCache"],
"settings": {
"securitySettings": {
"enableAdminLoginAsAnyUser": false
"enableAdminLoginAsAnyUser": true
},
"userManagementSettings": {
"enableEnhancedPermsetMgmt": true,
Expand Down
10 changes: 8 additions & 2 deletions nebula-cache-manager/core/classes/CacheManager.cls
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
// See LICENSE file or go to https://github.com/jongpie/NebulaCacheManager for full license details. //
//---------------------------------------------------------------------------------------------------//

@SuppressWarnings('PMD.ApexDoc, PMD.ExcessivePublicCount, PMD.PropertyNamingConventions')
@SuppressWarnings('PMD.ApexDoc, PMD.AvoidDebugStatements, PMD.AvoidGlobalModifier, PMD.ExcessivePublicCount, PMD.PropertyNamingConventions')
public without sharing class CacheManager {
@TestVisible
private static final Map<String, Cacheable> CONFIGURATION_DEVELOPER_NAME_TO_CACHEABLE_INSTANCE = new Map<String, Cacheable>();
@TestVisible
private static final List<CacheValue__mdt> CONFIGURED_CACHE_VALUES = Schema.CacheValue__mdt.getAll().values();
@TestVisible
private static final String CURRENT_VERSION_NUMBER = 'v1.0.2';
@TestVisible
private static final String PLATFORM_CACHE_NULL_VALUE = '<{(CACHE_VALUE_IS_NULL)}>'; // Presumably, no one will ever use this as an actual value
@TestVisible
private static final CacheConfiguration__mdt ORGANIZATION_CACHE_CONFIGURATION = Schema.CacheConfiguration__mdt.getInstance('Organization').clone();
Expand All @@ -30,6 +32,10 @@ public without sharing class CacheManager {
private set;
}

static {
System.debug(System.LoggingLevel.INFO, 'Nebula Cache Manager - Version Number: ' + CURRENT_VERSION_NUMBER);
}

@TestVisible
private enum PlatformCacheType {
ORGANIZATION,
Expand Down Expand Up @@ -133,7 +139,7 @@ public without sharing class CacheManager {
return keyToCacheValue;
}

@SuppressWarnings('PMD.CognitiveComplexity')
@SuppressWarnings('PMD.CognitiveComplexity, PMD.CyclomaticComplexity')
private class PlatformCache implements Cacheable {
private final PlatformCachePartitionProxy cachePartitionProxy;
private final CacheConfiguration__mdt configuration;
Expand Down
1 change: 0 additions & 1 deletion nebula-cache-manager/core/classes/CacheManager_Tests.cls
Original file line number Diff line number Diff line change
Expand Up @@ -709,7 +709,6 @@ private class CacheManager_Tests {
@IsTest
static void it_adds_configured_key_with_null_value_to_session_cache_when_session_platform_cache_is_available() {
String mockKey = 'SomeKey';
User mockValue = new User(Id = System.UserInfo.getUserId(), ProfileId = System.UserInfo.getProfileId());
CacheValue__mdt configuredCacheValue = new CacheValue__mdt(
Cache__c = CacheManager.SESSION_CACHE_CONFIGURATION.Id,
DataType__c = String.class.getName(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<PermissionSet xmlns="http://soap.sforce.com/2006/04/metadata">
<classAccesses>
<apexClass>CacheManager</apexClass>
<enabled>true</enabled>
</classAccesses>
<customMetadataTypeAccesses>
<enabled>true</enabled>
<name>CacheConfiguration__mdt</name>
</customMetadataTypeAccesses>
<customMetadataTypeAccesses>
<enabled>true</enabled>
<name>CacheValue__mdt</name>
</customMetadataTypeAccesses>
<hasActivationRequired>false</hasActivationRequired>
<label>Cache Manager: Admin</label>
</PermissionSet>
Loading

0 comments on commit 9c3ef74

Please sign in to comment.