Skip to content

Commit 38d6425

Browse files
Merge pull request #147 from forcedotcom/release-1.3.0
RELEASE @W-16879137@: Conducting v1.3.0 release
2 parents 84dcae5 + 460d63e commit 38d6425

17 files changed

+900
-292
lines changed

.github/workflows/daily-smoke-test.yml

+40
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,44 @@ jobs:
2828
create-vsix-artifact:
2929
name: 'Upload VSIX as artifact'
3030
uses: ./.github/workflows/create-vsix-artifact.yml
31+
# Step 4: Report any problems
32+
report-problems:
33+
name: 'Report problems'
34+
runs-on: ubuntu-latest
35+
needs: [build-scanner-tarball, smoke-test, create-vsix-artifact]
36+
if: ${{ failure() || cancelled() }}
37+
steps:
38+
- name: Report problems
39+
shell: bash
40+
env:
41+
IS_CRITICAL: ${{ contains(join(steps.*.outcome), 'failure') || contains(join(steps.*.outcome), 'skipped') }}
42+
RUN_LINK: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
43+
run: |
44+
if [[ ${{ env.IS_CRITICAL }} == true ]]; then
45+
ALERT_SEV="critical"
46+
ALERT_SUMMARY="Daily smoke test failed on ${{ runner.os }}"
47+
else
48+
ALERT_SEV="info"
49+
ALERT_SUMMARY="Daily smoke test succeeded with retries on ${{ runner.os }}"
50+
fi
3151
52+
generate_post_data() {
53+
cat <<EOF
54+
{
55+
"payload": {
56+
"summary": "${ALERT_SUMMARY}",
57+
"source": "Github Actions",
58+
"severity": "${ALERT_SEV}"
59+
},
60+
"links": [{
61+
"href": "${{ env.RUN_LINK }}",
62+
"text": "Link to action execution"
63+
}],
64+
"event_action": "trigger",
65+
"dedup_key": "GH-HB-${{ matrix.os.vm }}-${{ matrix.node }}",
66+
"routing_key": "${{ secrets.PAGERDUTY_HEARTBEAT_KEY }}"
67+
}
68+
EOF
69+
}
70+
71+
curl --request POST --data "$(generate_post_data)" https://events.pagerduty.com/v2/enqueue
+159
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
name: production-heartbeat
2+
on:
3+
workflow_dispatch: # As per documentation, the colon is necessary even though no config is required.
4+
schedule:
5+
# Cron syntax is "minute[0-59] hour[0-23] date[1-31] month[1-12] day[0-6]". '*' is 'any value', and multiple values
6+
# can be specified with comma-separated lists. All times are UTC.
7+
# So this expression means "run at 45 minutes past 1, 5, and 9 AM/PM UTC". The hours were chosen so that
8+
# the jobs run only close to business hours of Central Time.
9+
# Days were chosen to run only from Monday through Friday.
10+
- cron: '45 13,17,21 * * 1,2,3,4,5'
11+
jobs:
12+
production-heartbeat:
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
os: [{vm: ubuntu-latest}, {vm: windows-2019}, {vm: macos-latest}]
17+
node: ['lts/*']
18+
runs-on: ${{ matrix.os.vm }}
19+
timeout-minutes: 60
20+
steps:
21+
# 1 Install VS Code and Extension on Ubuntu
22+
- name: Install VS Code on Ubuntu
23+
if: runner.os == 'Linux'
24+
run: |
25+
sudo apt update
26+
sudo apt install wget gpg -y
27+
wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > packages.microsoft.gpg
28+
sudo install -o root -g root -m 644 packages.microsoft.gpg /usr/share/keyrings/
29+
sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main" > /etc/apt/sources.list.d/vscode.list'
30+
sudo apt update
31+
sudo apt install code -y
32+
33+
- name: Install Salesforce Code Analyzer Extension on Ubuntu
34+
if: runner.os == 'Linux'
35+
run: |
36+
code --install-extension salesforce.sfdx-code-analyzer-vscode
37+
38+
- name: Verify Extension Installation on Ubuntu
39+
if: runner.os == 'Linux'
40+
run: |
41+
if code --list-extensions | grep -q 'salesforce.sfdx-code-analyzer-vscode'; then
42+
echo "Extension installed successfully"
43+
else
44+
echo "::error Extension installation failed" && exit 1
45+
fi
46+
47+
# 2 Install VS Code and Extension on Windows
48+
# We use chocolatey to install vscode since it gives a reliable path for the location of code.exe
49+
# We have also seen Windows to be flaky, so adding addition echo statements.
50+
- name: Install VS Code on Windows
51+
if: runner.os == 'Windows'
52+
run: |
53+
Write-Host "Installing Chocolatey..."
54+
Set-ExecutionPolicy Bypass -Scope Process -Force;
55+
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
56+
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
57+
Write-Host "Installing Visual Studio Code using Chocolatey..."
58+
choco install vscode -y
59+
60+
- name: Install Salesforce Code Analyzer Extension on Windows
61+
if: runner.os == 'Windows'
62+
run: |
63+
echo "Installing Code Analyzer Extension..."
64+
"/c/Program Files/Microsoft VS Code/bin/code" --install-extension salesforce.sfdx-code-analyzer-vscode
65+
echo "Installing Code Analyzer Complete"
66+
67+
echo "Waiting for 10 seconds..."
68+
sleep 10
69+
70+
echo "Listing installed extensions..."
71+
"/c/Program Files/Microsoft VS Code/bin/code" --list-extensions
72+
shell: bash
73+
74+
- name: Verify Extension on Windows
75+
if: runner.os == 'Windows'
76+
run: |
77+
echo "Waiting for 10 seconds..."
78+
sleep 10
79+
80+
echo "Listing installed extensions..."
81+
extensions=$("/c/Program Files/Microsoft VS Code/bin/code" --list-extensions)
82+
83+
echo "$extensions"
84+
85+
if echo "$extensions" | grep -q 'salesforce.sfdx-code-analyzer-vscode'; then
86+
echo "Extension 'salesforce.sfdx-code-analyzer-vscode' is installed successfully"
87+
else
88+
echo "::error Extension 'salesforce.sfdx-code-analyzer-vscode' is NOT installed"
89+
exit 1
90+
fi
91+
shell: bash
92+
93+
# 3 Install VS Code and Extension on macOS
94+
- name: Install VS Code on macOS
95+
if: runner.os == 'macOS'
96+
run: |
97+
brew install --cask visual-studio-code
98+
99+
- name: Install Salesforce Code Analyzer Extension on macOS
100+
if: runner.os == 'macOS'
101+
run: |
102+
code --install-extension salesforce.sfdx-code-analyzer-vscode
103+
104+
- name: Verify Extension Installation on macOS
105+
if: runner.os == 'macOS'
106+
run: |
107+
if code --list-extensions | grep -q 'salesforce.sfdx-code-analyzer-vscode'; then
108+
echo "Extension installed successfully"
109+
else
110+
echo "::error Extension installation failed" && exit 1
111+
fi
112+
113+
# === Report any problems ===
114+
- name: Report problems
115+
# There are problems if any step failed or was skipped.
116+
# Note that the `join()` call omits null values, so if any steps were skipped, they won't have a corresponding
117+
# value in the string.
118+
if: ${{ failure() || cancelled() }}
119+
shell: bash
120+
env:
121+
# If we're here because steps failed or were skipped, then that's a critical problem. Otherwise it's a normal one.
122+
# We can't use the `failure()` or `cancelled()` convenience methods outside of the `if` condition, hence the
123+
# `contains()` calls.
124+
IS_CRITICAL: ${{ contains(join(steps.*.outcome), 'failure') || contains(join(steps.*.outcome), 'skipped') }}
125+
# A link to this run, so the PagerDuty assignee can quickly get here.
126+
RUN_LINK: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
127+
128+
run: |
129+
130+
if [[ ${{ env.IS_CRITICAL }} == true ]]; then
131+
ALERT_SEV="critical"
132+
ALERT_SUMMARY="Production heartbeat script failed on ${{ runner.os }}"
133+
else
134+
# Leaving the else part here to help with running end-to-end sanity test with real alerts being created.
135+
ALERT_SEV="info"
136+
ALERT_SUMMARY="Production heartbeat script succeeded with retries on ${{ runner.os }}"
137+
fi
138+
# Define a helper function to create our POST request's data, to sidestep issues with nested quotations.
139+
generate_post_data() {
140+
# This is known as a HereDoc, and it lets us declare multi-line input ending when the specified limit string,
141+
# in this case EOF, is encountered.
142+
cat <<EOF
143+
{"payload": {
144+
"summary": "${ALERT_SUMMARY}",
145+
"source": "Github Actions",
146+
"severity": "${ALERT_SEV}"
147+
},
148+
"links": [{
149+
"href": "${{ env.RUN_LINK }}",
150+
"text": "Link to action execution"
151+
}],
152+
"event_action": "trigger",
153+
"dedup_key": "GH-HB-${{ matrix.os.vm }}-${{ matrix.node }}",
154+
"routing_key": "${{ secrets.PAGERDUTY_HEARTBEAT_KEY }}"
155+
}
156+
EOF
157+
}
158+
# Make our POST request
159+
curl --request POST --data "$(generate_post_data)" https://events.pagerduty.com/v2/enqueue

SHA256.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ make sure that their SHA values match the values in the list below.
1515
shasum -a 256 <location_of_the_downloaded_file>
1616

1717
3. Confirm that the SHA in your output matches the value in this list of SHAs.
18-
f668893331860e3b8bc89357c4bfe2cac9840ee05acd1b0d67de5a8c37518b87 ./extensions/sfdx-code-analyzer-vscode-1.1.0.vsix
18+
146d022eebef24a355b117ad38713ac53a006f8e74cae178c6364a302878d3bc ./extensions/sfdx-code-analyzer-vscode-1.2.0.vsix
1919
4. Change the filename extension for the file that you downloaded from .zip to
2020
.vsix.
2121

package.json

+9-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"color": "#ECECEC",
1414
"theme": "light"
1515
},
16-
"version": "1.2.0",
16+
"version": "1.3.0",
1717
"publisher": "salesforce",
1818
"license": "BSD-3-Clause",
1919
"engines": {
@@ -57,6 +57,7 @@
5757
"mocha": "^10.1.0",
5858
"nyc": "^15.1.0",
5959
"ovsx": "^0.8.3",
60+
"proxyquire": "^2.1.3",
6061
"sinon": "^15.1.0",
6162
"ts-node": "^10.9.1",
6263
"typescript": "^4.9.3"
@@ -101,7 +102,7 @@
101102
},
102103
{
103104
"command": "sfca.runDfa",
104-
"title": "***SFDX: Run Graph-Engine Based Analysis***"
105+
"title": "SFDX: Scan Project with Graph Engine Path-Based Analysis"
105106
},
106107
{
107108
"command": "sfca.runApexGuruAnalysisOnSelectedFile",
@@ -167,6 +168,11 @@
167168
"type": "boolean",
168169
"default": false,
169170
"description": "Discover critical problems and performance issues in your Apex code with ApexGuru, which analyzes your Apex files for you. This feature is in a closed pilot; contact your account representative to learn more."
171+
},
172+
"codeAnalyzer.partialGraphEngineScans.enabled": {
173+
"type": "boolean",
174+
"default": false,
175+
"description": "Enables partial Salesforce Graph Engine scans on only the code you've modified since the initial full scan. (Beta)"
170176
}
171177
}
172178
},
@@ -186,7 +192,7 @@
186192
},
187193
{
188194
"command": "sfca.runDfa",
189-
"when": "false"
195+
"when": "sfca.partialRunsEnabled"
190196
},
191197
{
192198
"command": "sfca.removeDiagnosticsOnActiveFile",

src/apexguru/apex-guru-service.ts

+9-2
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ export async function runApexGuruOnFile(selection: vscode.Uri, runInfo: RunInfo)
5757
new DiagnosticManager().displayDiagnostics([selection.fsPath], [ruleResult], diagnosticCollection);
5858
TelemetryService.sendCommandEvent(Constants.TELEM_SUCCESSFUL_APEX_GURU_FILE_ANALYSIS, {
5959
executedCommand: commandName,
60-
duration: (Date.now() - startTime).toString()
60+
duration: (Date.now() - startTime).toString(),
61+
violationsCount: ruleResult.violations.length.toString(),
62+
violationsWithSuggestedCodeCount: getViolationsWithSuggestions(ruleResult).toString()
6163
});
6264
void vscode.window.showInformationMessage(messages.apexGuru.finishedScan(ruleResult.violations.length));
6365
});
@@ -68,6 +70,11 @@ export async function runApexGuruOnFile(selection: vscode.Uri, runInfo: RunInfo)
6870
}
6971
}
7072

73+
export function getViolationsWithSuggestions(ruleResult: RuleResult): number {
74+
// Filter violations that have a non-empty suggestedCode and get count
75+
return ruleResult.violations.filter(violation => (violation as ApexGuruViolation).suggestedCode?.trim() !== '').length;
76+
}
77+
7178
export async function pollAndGetApexGuruResponse(connection: Connection, requestId: string, maxWaitTimeInSeconds: number, retryIntervalInMillis: number): Promise<ApexGuruQueryResponse> {
7279
let queryResponse: ApexGuruQueryResponse;
7380
let lastErrorMessage = '';
@@ -147,7 +154,7 @@ export function transformStringToRuleResult(fileName: string, jsonString: string
147154
column: 1,
148155
currentCode: Buffer.from(encodedCodeBefore, 'base64').toString('utf8'),
149156
suggestedCode: Buffer.from(encodedCodeAfter, 'base64').toString('utf8'),
150-
url: fileName
157+
url: 'https://help.salesforce.com/s/articleView?id=sf.apexguru_antipatterns.htm&type=5'
151158
};
152159

153160
ruleResult.violations.push(violation);

src/deltarun/delta-run-service.ts

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (c) 2024, Salesforce, Inc.
3+
* All rights reserved.
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6+
*/
7+
import * as fs from 'fs';
8+
9+
export function getDeltaRunTarget(sfgecachepath:string, savedFilesCache:Set<string>): string[] {
10+
// Read and parse the JSON file at sfgecachepath
11+
const fileContent = fs.readFileSync(sfgecachepath, 'utf-8');
12+
const parsedData = JSON.parse(fileContent) as CacheData;
13+
14+
const matchingEntries: string[] = [];
15+
16+
// Iterate over each file entry in the data
17+
parsedData.data.forEach((entry: { filename: string, entries: string[] }) => {
18+
// Check if the filename is in the savedFilesCache
19+
if (savedFilesCache.has(entry.filename)) {
20+
// If it matches, add the individual entries to the result array
21+
matchingEntries.push(...entry.entries);
22+
}
23+
});
24+
25+
return matchingEntries;
26+
}
27+
28+
interface CacheEntry {
29+
filename: string;
30+
entries: string[];
31+
}
32+
33+
interface CacheData {
34+
data: CacheEntry[];
35+
}

0 commit comments

Comments
 (0)