Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
aee6d38
Update GitHub Actions workflow to save deployment data and configure …
ZackFra Jan 5, 2025
752c1b7
Add NextNQuartersParser class and update Token with NEXT_N_QUARTERS_L…
ZackFra Jan 5, 2025
d5be79c
Refactor AWS deployment scripts: update validate workflow to pass par…
ZackFra Jan 5, 2025
72dfb23
Update validate workflow to replace invoke-save-deployment-func.sh wi…
ZackFra Jan 5, 2025
62e4cee
Fix shebang line in AWS scripts and remove unnecessary lines
ZackFra Jan 5, 2025
ea0903a
Add shebang lines to AWS scripts for improved compatibility
ZackFra Jan 5, 2025
7357b82
Update validate workflow to use file URI for validate.json in invoke-…
ZackFra Jan 5, 2025
4526116
Refactor validate workflow to format deployment data before invoking …
ZackFra Jan 5, 2025
c12ad69
Update validate workflow to include repository and pull request numbe…
ZackFra Jan 5, 2025
fd479a1
Fix pull request URL formatting in deployment data
ZackFra Jan 5, 2025
2f86f02
Update invoke-lambda-func.sh to use deployment-request.json and handl…
ZackFra Jan 5, 2025
724bfa9
Pass AWS credentials as arguments to config-aws.sh for improved secur…
ZackFra Jan 5, 2025
61fbfd6
Update AWS credentials variable names in validate workflow for consis…
ZackFra Jan 5, 2025
54c2d47
Refactor AWS configuration in validate workflow to use environment va…
ZackFra Jan 5, 2025
b4475e7
Refactor validate workflow to use environment variables for repositor…
ZackFra Jan 5, 2025
0486634
Add save-deployment.sh script to streamline AWS deployment process
ZackFra Jan 5, 2025
019d844
Add SF_AUTH_URL to validate workflow and create script for auth file …
ZackFra Jan 5, 2025
715cc0f
Rename auth file creation script for clarity in validate workflow
ZackFra Jan 5, 2025
3042b57
Add AWS_GET_DEPLOYMENT_FUNC to validate workflow and implement get-de…
ZackFra Jan 5, 2025
acf196a
Fix get-deployment script to output to outfile.json instead of found-…
ZackFra Jan 5, 2025
013b0dc
Refactor deployment workflow to use scripts for auth file creation an…
ZackFra Jan 5, 2025
c340a01
Update get-deployment script to read Quick Deploy ID from job-id.txt …
ZackFra Jan 5, 2025
dcd6872
Update deployment workflow to retrieve Quick Deploy ID from job-id.tx…
ZackFra Jan 5, 2025
b97f2ae
Add step to echo Quick Deploy ID in validate workflow
ZackFra Jan 5, 2025
5dfa13b
Fix typo in get-job-id.js to correct 'provess' to 'process'
ZackFra Jan 5, 2025
e4403f3
Fix validation job parsing to use correct status property
ZackFra Jan 5, 2025
628880a
Fix incorrect property reference in parseValidateJob function
ZackFra Jan 5, 2025
ccc0054
Handle job validation failure by exiting the process instead of writi…
ZackFra Jan 5, 2025
156f586
Refactor error handling in job validation to exit process on parse fa…
ZackFra Jan 5, 2025
5fdf15d
Throw error on job validation failure instead of logging to console
ZackFra Jan 5, 2025
71bb730
Fix property reference in parseValidateJob to use deploymentStatus fo…
ZackFra Jan 5, 2025
085f30d
Add output display for deployment script and retrieve job ID
ZackFra Jan 5, 2025
d0e0db4
Add unit test for NextNQuartersParser to ensure correct parsing of NE…
ZackFra Jan 5, 2025
a267e70
Add parser and test for NEXT_N_QUARTERS_LITERAL
ZackFra Jan 5, 2025
d5f5a87
Fix test to use NextNQuartersParser instead of NextNQuarters for corr…
ZackFra Jan 5, 2025
711fe70
Rename quick deploy step to deployment in workflows and remove redund…
ZackFra Jan 5, 2025
a408885
Add NextNQuartersComparable class and related tests for parsing NEXT_…
ZackFra Jan 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ jobs:
runs-on: ubuntu-latest
if: ${{ !contains(github.event.pull_request.labels.*.name, 'dont deploy') && github.event.pull_request.merged == true }}
steps:
- uses: 8BitJonny/[email protected]
id: PR
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Create Auth File
run: |
echo '{"sfdxAuthUrl": "${{ secrets.SF_AUTH_URL }}"}' > authFile.json
run: scripts/bash/create-sfdx-auth-file.sh
- name: Get Deployment
id: get_deployment
run: scripts/bash/get-deployment.sh
- uses: ZackFra/sf-delta-deploy@master
with:
branch: origin/main
quick-deploy-id: ${{ steps.PR.outputs.pr_body }}
quick-deploy-id: ${{ steps.get_deployment.outputs.quick-deploy-id }}
26 changes: 14 additions & 12 deletions .github/workflows/validate.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ on:
paths:
- "**/main/default/**"

env:
AWS_SECRET: ${{ secrets.AWS_SECRET }}
AWS_ACCESS_KEY: ${{ secrets.AWS_ACCESS_KEY }}
AWS_REGION: ${{ secrets.AWS_REGION }}
AWS_SAVE_DEPLOYMENT_FUNC: ${{ secrets.AWS_SAVE_DEPLOYMENT_FUNC }}
AWS_GET_DEPLOYMENT_FUNC: ${{ secrets.AWS_GET_DEPLOYMENT_FUNC }}
SF_AUTH_URL: ${{ secrets.SF_AUTH_URL }}
REPOSITORY: ${{ github.repository }}
PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}

jobs:
validate-pull-request:
permissions: write-all
Expand All @@ -41,19 +51,11 @@ jobs:
with:
fetch-depth: 0
- name: Create Auth File
run: |
echo '{"sfdxAuthUrl": "${{ secrets.SF_AUTH_URL }}"}' > authFile.json
run: scripts/bash/create-sfdx-auth-file.sh
- uses: ZackFra/sf-delta-validate@master
with:
branch: origin/main
- name: Get Job Id
run: |
node scripts/js/get-job-id.js
- name: Update PR Description
uses: nefrob/[email protected]
with:
content: job-id.txt
contentIsFilePath: true
regex: ".*"
token: ${{ secrets.GITHUB_TOKEN }}
auth-file: authFile.json
- name: Save To Database
run: scripts/bash/save-deployment.sh

1 change: 1 addition & 0 deletions authFile.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"sfdxAuthUrl": "$SF_AUTH_URL"}
Original file line number Diff line number Diff line change
Expand Up @@ -3900,11 +3900,11 @@ private class MockDatabaseTest {
@isTest
static void ensureNextQuarterInWhereClause() {
List<Opportunity> oppList = new List<Opportunity>();
Date startOfYear = Date.newInstance(Gmt.today().year(), 1, 1);
Date today = Gmt.today();
for(Integer i = 0; i < 12; i++) {
oppList.add(new Opportunity(
Name = 'Opp' + i,
CloseDate = startOfYear.addMonths(i)
CloseDate = today.addMonths(i)
));
}

Expand All @@ -3917,4 +3917,25 @@ private class MockDatabaseTest {

Assert.areEqual(3, opportunities.size(), 'Incorrect number of opportunities');
}

@isTest
static void ensureNextNQuartersWorksInWhereClause() {

List<Opportunity> oppList = new List<Opportunity>();
Date today = Gmt.today();
for(Integer i = 0; i < 12; i++) {
oppList.add(new Opportunity(
Name = 'Opp' + i,
CloseDate = today.addMonths(i)
));
}

MockDatabase.doInsert(oppList, true);

Test.startTest();
List<Opportunity> opportunities = MockDatabase.query('SELECT Id FROM Opportunity WHERE CloseDate = NEXT_N_QUARTERS:2');
Test.stopTest();

Assert.areEqual(6, opportunities.size(), 'Incorrect number of opportunities');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ public with sharing class DateLiteralComparableFactory {
Token.N_MONTHS_AGO_LITERAL => NMonthsAgoComparable.class,
Token.THIS_QUARTER_LITERAL => ThisQuarterComparable.class,
Token.LAST_QUARTER_LITERAL => LastQuarterComparable.class,
Token.NEXT_QUARTER_LITERAL => NextQuarterComparable.class
Token.NEXT_QUARTER_LITERAL => NextQuarterComparable.class,
Token.NEXT_N_QUARTERS_LITERAL => NextNQuartersComparable.class
};

@TestVisible
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* @description Comparable for the NEXT_N_QUARTERS token
* @author Zackary Frazier
* @since 1/4/2025
*/
public with sharing class NextNQuartersComparable extends DateLiteralComparable {
/**
* @description Returns whether fieldValue is in the NEXT_N_QUARTERS
* @param fieldValue `Datetime`
* @return `Boolean`
*/
public override Boolean isEqual(Datetime fieldValue) {
Datetime startOfNextQuarter = Gmt.startOfThisCalendarQuarter().addMonths(3);
String nQuarters = this.token.split(':')[1];
Integer nQuartersInt = Integer.valueOf(nQuarters);
Datetime nextNQuarters = startOfNextQuarter.addMonths(nQuartersInt * 3);

return startOfNextQuarter <= fieldValue && fieldValue < nextNQuarters;
}

/**
* @description Returns whether fieldValue is less than NEXT_N_QUARTERS
* @param fieldValue `Datetime`
* @return `Boolean`
*/
public override Boolean isLessThan(Datetime fieldValue) {
return fieldValue < Gmt.startOfThisCalendarQuarter().addMonths(3);
}

/**
* @description Return whether fieldValue is greater than NEXT_N_QUARTERS
* @param fieldValue `Datetime`
* @return `Boolean`
*/
public override Boolean isGreaterThan(Datetime fieldValue) {
String nQuarters = this.token.split(':')[1];
Integer nQuartersInt = Integer.valueOf(nQuarters);
Datetime startOfNextQuarter = Gmt.startOfThisCalendarQuarter().addMonths(3);
Datetime nextNQuarters = startOfNextQuarter.addMonths(nQuartersInt * 3);

return fieldValue >= nextNQuarters;
}
}
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>62.0</apiVersion>
<status>Active</status>
</ApexClass>
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
@isTest
private class NextNQuartersComparableTest {

@isTest
static void ensureIsEqualWorks() {
DateLiteralComparable nextNQuarters = new NextNQuartersComparable().withToken('NEXT_N_QUARTERS:5');
Datetime startOfNextQuarter = Gmt.startOfThisCalendarQuarter().addMonths(3);
Assert.isFalse(
nextNQuarters.isEqual(Gmt.today()),
'Today should not be equal to NEXT_N_QUARTERS:5'
);

Assert.isTrue(
nextNQuarters.isEqual(startOfNextQuarter.addMonths(3 * 5).addDays(-1)),
'isEqual should return true when fieldValue is in the next 5 quarters'
);

Assert.isFalse(
nextNQuarters.isEqual(startOfNextQuarter.addMonths(3 * 6)),
'isEqual should return false when fieldValue is not in the next 5 quarters'
);
}

@isTest
static void ensuresIsLessThanWorks() {
DateLiteralComparable nextNQuarters = new NextNQuartersComparable().withToken('NEXT_N_QUARTERS:5');

Assert.isTrue(
nextNQuarters.isLessThan(Gmt.startOfThisCalendarQuarter().addMonths(3).addDays(-1)),
'isLessThan should return true when fieldValue is not in the next quarter'
);

Assert.isFalse(
nextNQuarters.isLessThan(Gmt.startOfThisCalendarQuarter().addMonths(3 * 5)),
'isLessThan should return false when fieldValue is in the next 5 quarters'
);
}

@isTest
static void ensuresIsGreaterThanWorks() {
DateLiteralComparable nextNQuarters = new NextNQuartersComparable().withToken('NEXT_N_QUARTERS:5');
Datetime startOfNextQuarter = Gmt.startOfThisCalendarQuarter().addMonths(3);
Assert.isTrue(
nextNQuarters.isGreaterThan(startOfNextQuarter.addMonths(3 * 5)),
'isGreaterThan should return true when fieldValue is not in the next 5 quarters'
);

Assert.isFalse(
nextNQuarters.isGreaterThan(startOfNextQuarter.addMonths(3 * 5).addDays(-1)),
'isGreaterThan should return false when fieldValue is in the next 5 quarters'
);
}

@isTest
static void ensureIsLessThanOrEqualWorks() {
DateLiteralComparable nextNQuarters = new NextNQuartersComparable().withToken('NEXT_N_QUARTERS:5');
Datetime startOfNextQuarter = Gmt.startOfThisCalendarQuarter().addMonths(3);

Assert.isTrue(
nextNQuarters.isLessThanOrEqual(startOfNextQuarter.addDays(-1)),
'isLessThanOrEqual should return true when fieldValue is not in the next quarter'
);

Assert.isTrue(
nextNQuarters.isLessThanOrEqual(startOfNextQuarter.addMonths(3 * 5).addDays(-1)),
'isLessThanOrEqual should return true when fieldValue is in the next 5 quarters'
);

Assert.isFalse(
nextNQuarters.isLessThanOrEqual(startOfNextQuarter.addMonths(3 * 5)),
'isLessThanOrEqual should return false when fieldValue is not in the next 5 quarters'
);
}

@isTest
static void ensuresIsGreaterThanOrEqualWorks() {
DateLiteralComparable nextNQuarters = new NextNQuartersComparable().withToken('NEXT_N_QUARTERS:5');
Datetime nextCalendarQuarter = Gmt.startOfThisCalendarQuarter().addMonths(3);

Assert.isTrue(
nextNQuarters.isGreaterThanOrEqual(nextCalendarQuarter.addMonths(3 * 6)),
'isGreaterThanOrEqual should return true when fieldValue is in the next 5 quarters'
);

Assert.isTrue(
nextNQuarters.isGreaterThanOrEqual(nextCalendarQuarter.addMonths(3 * 5).addMonths(1)),
'isGreaterThanOrEqual should return true when fieldValue is in the next 5 quarters'
);

Assert.isFalse(
nextNQuarters.isGreaterThanOrEqual(Gmt.startOfThisCalendarQuarter()),
'isGreaterThanOrEqual should return false when fieldValue is not in the next 5 quarters'
);
}

@isTest
static void ensureIsNotEqualWorks() {
DateLiteralComparable nextNQuarters = new NextNQuartersComparable().withToken('NEXT_N_QUARTERS:5');

Assert.isTrue(
nextNQuarters.isNotEqual(Gmt.today()),
'Today should not be equal to NEXT_N_QUARTERS:5'
);

Datetime startOfNextQuarter = Gmt.startOfThisCalendarQuarter().addMonths(3);

Assert.isFalse(
nextNQuarters.isNotEqual(startOfNextQuarter.addMonths(3 * 5).addDays(-1)),
'isNotEqual should return false when fieldValue is in the next 5 quarters'
);

Assert.isTrue(
nextNQuarters.isNotEqual(startOfNextQuarter.addMonths(3 * 5)),
'isNotEqual should return true when fieldValue is not in the next 5 quarters'
);
}
}
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>62.0</apiVersion>
<status>Active</status>
</ApexClass>
Original file line number Diff line number Diff line change
Expand Up @@ -418,4 +418,17 @@ private class ParserTest {
}
Test.stopTest();
}

@isTest
static void ensureParserCanParseNextNQuarters() {
Parser p = new Parser();
String soqlQuery = 'SELECT Id FROM Opportunity WHERE CreatedDate = NEXT_N_QUARTERS:5';
Test.startTest();
try {
p.parse(soqlQuery);
} catch(Exception e) {
Assert.fail('Expected no exception but got ' + e.getMessage() + ' for ' + soqlQuery);
}
Test.stopTest();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public with sharing class PrimitiveParserFactory {
Token.THIS_QUARTER_LITERAL => ThisQuarterParser.class,
Token.LAST_QUARTER_LITERAL => LastQuarterParser.class,
Token.NEXT_QUARTER_LITERAL => NextQuarterParser.class,
Token.NEXT_N_QUARTERS_LITERAL => NextNQuartersParser.class,
Token.XTRUE => BooleanParser.class,
Token.XFALSE => BooleanParser.class,
Token.XNULL => NullParser.class,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* @description Parser for the NEXT_N_QUARTERS_LITERAL
* @author Zackary Frazier
* @since 1/4/2025
*/
public with sharing class NextNQuartersParser extends DateLiteralParser {
/**
* @description Parses the NEXT_N_QUARTERS_LITERAL
* @param query `String`
* @return `Intermediary`
*/
public override Intermediary parse(String query) {
return parseNDays(query, Token.NEXT_N_QUARTERS_LITERAL);
}
}
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>62.0</apiVersion>
<status>Active</status>
</ApexClass>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@isTest
private class NextNQuartersParserTest {

@IsTest
static void ensureNextNQuartersCanBeParsed() {
Assert.isTrue(
DateLiteralParserTestUtil.ensureVariableTokenCanBeParsed('NEXT_N_QUARTERS:5', new NextNQuartersParser()),
'NEXT_N_QUARTERS should be parsed'
);
}
}
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>62.0</apiVersion>
<status>Active</status>
</ApexClass>
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,5 @@ public inherited sharing class Token {
public final static String THIS_QUARTER_LITERAL = 'this_quarter';
public final static String LAST_QUARTER_LITERAL = 'last_quarter';
public final static String NEXT_QUARTER_LITERAL = 'next_quarter';
public final static String NEXT_N_QUARTERS_LITERAL = 'next_n_quarters';
}
6 changes: 6 additions & 0 deletions scripts/bash/config-aws.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env bash
npm i -g aws-cdk
aws configure set aws_access_key_id $AWS_ACCESS_KEY
aws configure set aws_secret_access_key $AWS_SECRET
aws configure set default.region $AWS_REGION
aws configure set default.output json
2 changes: 2 additions & 0 deletions scripts/bash/create-sfdx-auth-file.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/usr/bin/env bash
echo "{\"sfdxAuthUrl\": \"$SF_AUTH_URL\"}" > authFile.json
6 changes: 6 additions & 0 deletions scripts/bash/get-deployment.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env bash
scripts/bash/config-aws.sh
scripts/bash/invoke-lambda-func.sh "{\"pullRequestUrl\":\"/$REPOSITORY/pull/$PULL_REQUEST_NUMBER\"}" $AWS_GET_DEPLOYMENT_FUNC
cat outfile.json
node scripts/js/get-job-id.js "outfile.json"
echo "quick-deploy-id=$(cat job-id.txt)" >> "$GITHUB_OUTPUT"
2 changes: 2 additions & 0 deletions scripts/bash/invoke-lambda-func.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/usr/bin/env bash
aws lambda invoke --payload $1 --function-name $2 --cli-binary-format raw-in-base64-out outfile.json
4 changes: 4 additions & 0 deletions scripts/bash/save-deployment.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
scripts/bash/config-aws.sh
node scripts/js/format-deployment-data.js "validate.json"
scripts/bash/invoke-lambda-func.sh "file://deployment-request.json" $AWS_SAVE_DEPLOYMENT_FUNC
Loading
Loading