@salesforce/lds-core-release 1.243.0 → 1.245.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +2 -57
  2. package/package.json +1 -1
  3. package/src/release.py +104 -26
package/README.md CHANGED
@@ -1,58 +1,3 @@
1
- # LDS Release
1
+ # LDS Core Release
2
2
 
3
- ## Prerequisites
4
-
5
- 1. make sure you have `python3` on your PATH
6
- 2. make sure you have either run `yarn build:core-artifacts` from the root of the repo to generate the artifacts, or downloaded and unzipped a Github release artifact
7
-
8
- ## How to run locally
9
-
10
- It's really simple, just run `yarn release:python` from this package, then use the prompts to give the path to your release artifact dir and the path to your core.
11
-
12
- ## Running a release on a Salesforce workspace
13
-
14
- This part assumes you have a [Salesforce workspace available](https://sfdc.co/ws), and using the **Core on Git** Workspace template. This script does not handle p4 commands.
15
-
16
- 1. `cd` out of the core path to something like `/opt/workspace`. Make a working directory for yourself here. `mkdir lds`, and `cd` into it.. `cd lds`
17
- 2. Authenticate to Github.com via the installed github cli. `gh auth login`. Make sure you're logged into your EMU account. Specify that HTTPS is fine for git operations. You'll have to paste an auth code to login.
18
- 3. Download the release artifact for the version you're trying to release. `gh release download {release version} --repo=salesforce-experience-platform-emu/lds-lightning-platform`
19
- 4. Unzip the release artifact. `unzip sfdc.zip`
20
- 5. Run the release script that is included in the artifact. `python3 output/lds/release.py`
21
-
22
- - Answer the prompts to point the script to the right directories. To clarify, this is the `sfdc` directory in the unzipped dir.
23
-
24
- ```
25
- python output/lds/release.py
26
- Enter the location of the LDS release artifact. Default: ../../output/sfdc: ./output/sfdc
27
- Enter the core filepath. Default: /Users/scarraway/repositories/salesforce/core/core-public/core: /opt/workspace/core-public/core
28
- Source filepath: output/sfdc
29
- ```
30
-
31
- - Validate the changes look correct
32
-
33
- 6. Create a branch with all the changes and submit for review.
34
-
35
- ## Troubleshooting
36
-
37
- If you see an error with Git LFS when pushing, you may need to force another change to get LFS up to date.
38
- Example:
39
-
40
- ```
41
- Spawned process 5149 to upload telemetry. Logs at /opt/workspace/gimlet-home/logs/20230712141414/telemetry-upload.nohup.out
42
- Your token to access the Git-lfs instance (https://gitlfs.soma.salesforce.com/artifactory/api/lfs/gitlfs-coreapp) is valid.
43
- Preparing lfs
44
- Git LFS upload failed: 33% (1/3), 4.6 KB | 0 B/s
45
- (missing) core/ui-force-components/modules/force/ldsAdaptersUiapi/ldsAdaptersUiapi.js (06dcf9a38c6a94e13f9d687b215f3a55d2243df2e2cf19b4464eac964e2824f2)
46
- (missing) core/ui-force-components/modules/force/ldsAdaptersAnalyticsWave/ldsAdaptersAnalyticsWave.js (9479f6181b61748b5a1256d9df726746df8982f5486043cb81d0b08408fac0bc)
47
- hint: Your push was rejected due to missing or corrupt local objects.
48
- hint: You can disable this check with: `git config lfs.allowincompletepush true`
49
- Uploading LFS objects: 33% (1/3), 4.6 KB | 0 B/s, done.
50
- error: failed to push some refs to 'https://gitcore.soma.salesforce.com/core-2206/core-public.git'
51
- ```
52
-
53
- **CAUTION** Do NOT run `git config lfs.allowincompletepush true`. It can lead to NPE when core-on-git is building your branch.
54
-
55
- Instead you can
56
-
57
- 1. Make a whitespace change and re-push those files to your branch.
58
- 2. Use `git lfs pull --include ui-force-components/modules/force/ldsAdaptersAnalyticsWave/ldsAdaptersAnalyticsWave.js` for each file complained about above. This forces your local git to pull down the LFS files. Then make a whitespace change and re-push.
3
+ This package defines a portable [python script](./src/release.py) along with assets to successfully update core with the latest lds-lightning-platform assets. It can be used for local development, integration testing, and the LDS weekly release. Usage is documented [here](../../docs/release/core-release-tasks.md)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@salesforce/lds-core-release",
3
3
  "private": false,
4
- "version": "1.243.0",
4
+ "version": "1.245.0",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "description": "LDS release System",
7
7
  "scripts": {
package/src/release.py CHANGED
@@ -1,35 +1,96 @@
1
1
  #!/usr/bin/env python3
2
- import shutil
2
+ import subprocess;
3
+ import errno;
3
4
  from string import Template
4
5
  from pathlib import Path
5
6
  from typing import List
6
7
  from functools import lru_cache
8
+ import asyncio
9
+ import argparse
7
10
 
8
11
  # resolve static files used by the script
9
12
  script_path = Path(__file__).resolve()
10
13
  script_directory = script_path.parent
11
14
  assets_path = script_directory / 'assets'
12
15
 
16
+ async def usingPerforce(coreDir):
17
+ isPerforceDir = True
18
+ try:
19
+ # Run the 'p4 where ...' command using subprocess
20
+ result = subprocess.run(['p4 where ...'], cwd=coreDir, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, check=True)
21
+ # Check if the error message indicates the directory is not under client's root
22
+ if "is not under client's root" in result.stderr:
23
+ print('Client root error!')
24
+ isPerforceDir = False
25
+
26
+ except subprocess.CalledProcessError as e:
27
+ print('Got an error trying to verify p4 workspace. Assuming Git.')
28
+ print(e)
29
+ # Handle any errors, but we assume that if 'p4 where' fails, it's not a Perforce directory
30
+ isPerforceDir = False
31
+
32
+ return isPerforceDir
33
+
34
+ async def checkoutFileP4(corePath: Path, coreDir: Path):
35
+ # Check if the file exists
36
+ if not corePath.exists():
37
+ # If it doesn't exist, add it to Perforce
38
+ print('New file in perforce. Attempting add.')
39
+ p4_command = [f'p4 add {corePath}']
40
+
41
+ try:
42
+ subprocess.run(p4_command, cwd=coreDir, check=True, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
43
+ except subprocess.CalledProcessError as e:
44
+ print(f"Error adding file to Perforce: {e}")
45
+ return
46
+
47
+ # Create the directory structure if it doesn't exist
48
+ corePath.parent.mkdir(parents=True, exist_ok=True)
49
+
50
+ # Create an empty file
51
+ try:
52
+ corePath.touch()
53
+ except OSError as e:
54
+ if e.errno == errno.EACCES:
55
+ print(f"File is not writable. Make sure to run 'p4 edit {corePath}'.")
56
+ else:
57
+ print(f"Error creating file: {e}")
58
+ else:
59
+ # If the file exists, edit it in Perforce
60
+ p4_command = [f'p4 edit {corePath}']
61
+
62
+ try:
63
+ subprocess.run(p4_command, cwd=coreDir, check=True, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
64
+ except subprocess.CalledProcessError as e:
65
+ print(f"Error editing file in Perforce: {e}")
66
+
67
+ # Check if the file is writable
68
+ try:
69
+ corePath.touch(mode=0o666, exist_ok=True)
70
+ except OSError as e:
71
+ if e.errno == errno.EACCES:
72
+ print(f"File is not writable. Make sure to run 'p4 edit {corePath}'.")
73
+ else:
74
+ print(f"Error checking file access: {e}")
75
+
13
76
  # Python 3 script that does the LDS release.
14
- def copy_release(source_dir: Path, destination_dir: Path):
77
+ async def copy_release(source_dir: Path, destination_dir: Path, useP4: bool):
15
78
  try:
16
79
  new_modules = []
17
80
 
18
- # Create the destination directory if it doesn't exist
19
- if not destination_dir.exists():
20
- destination_dir.mkdir(parents=True)
21
-
22
81
  # Copy files from the source directory to the destination directory
23
82
  for file in Path(source_dir).rglob("*.js"):
24
83
  print(f"File detected: {file}")
25
84
 
26
85
  relative_path = file.relative_to(source_dir)
27
- print(f"relative path: {relative_path}")
28
86
  destination_file = destination_dir / relative_path
87
+
88
+ if(useP4):
89
+ await checkoutFileP4(destination_file, destination_dir)
90
+
29
91
  destination_file.parent.mkdir(parents=True, exist_ok=True)
30
92
  destination_file.touch(mode= 0o666 ,exist_ok=True)
31
93
 
32
- print(f"Trying to copy file: {relative_path}")
33
94
  # Copy the file
34
95
  destination_file.write_bytes(file.read_bytes())
35
96
  # Get the directory name (module name)
@@ -43,6 +104,8 @@ def copy_release(source_dir: Path, destination_dir: Path):
43
104
  new_modules.append(module_name)
44
105
  # Create the meta xml file if missing
45
106
  meta_xml_template_bytes = read_js_meta_template()
107
+ if(useP4):
108
+ await checkoutFileP4(meta_xml_file, destination_dir)
46
109
  meta_xml_file.touch(mode= 0o666 ,exist_ok=True)
47
110
  meta_xml_file.write_bytes(meta_xml_template_bytes)
48
111
 
@@ -85,36 +148,51 @@ def replace_string_in_file(file_path: Path, old_string: str, new_string: str, su
85
148
  except Exception as e:
86
149
  print("An error occurred while replacing the string:", e)
87
150
 
88
- def update_ownership_yml(destination_filepath: Path, new_modules: List[str]):
89
- if(len(new_modules) == 0):
90
- return
91
-
151
+ async def update_ownership_yml(destination_filepath: Path, new_modules: List[str], useP4: bool):
92
152
  ownershipYamlPath = destination_filepath / 'ui-force-components' / 'java' / 'resources' / 'ownership.yaml'
93
153
  newEntriesString = "\n".join([f" - modules/force/{module}/**" for module in new_modules]) + "\n - modules/force/ldsBindings/**"
154
+ if useP4:
155
+ await checkoutFileP4(ownershipYamlPath, destination_filepath)
94
156
  ownershipYamlPath.chmod(0o666)
95
157
  replace_string_in_file(ownershipYamlPath, ' - modules/force/ldsBindings/**', newEntriesString, "Updated ownership.yml")
96
158
  return
97
159
 
98
- def update_lwc_workflow_test(destination_filepath: Path, new_modules: List[str]):
99
- if(len(new_modules) == 0):
100
- return
101
-
160
+ async def update_lwc_workflow_test(destination_filepath: Path, new_modules: List[str], useP4: bool):
102
161
  lwcWorkflowTestPath = destination_filepath / 'aura-impl-sfdc' / 'test' / 'func' / 'java' / 'src' / 'aura' / 'impl' / 'sfdc' / 'modules' / 'LWCWorkflowTest.java'
103
162
  newEntriesString = "\n".join([f' "force/{module}",' for module in new_modules]) + '\n "force/ldsBindings",'
163
+ if useP4:
164
+ await checkoutFileP4(lwcWorkflowTestPath, destination_filepath)
165
+
104
166
  lwcWorkflowTestPath.chmod(0o666)
105
167
  replace_string_in_file(lwcWorkflowTestPath, ' "force/ldsBindings",', newEntriesString, "Updated LWCWorkflowTest")
106
168
  return
107
169
 
108
- # Accept input from the user
109
- source_filepath = Path(input("Enter the location of the LDS release artifact. Default: ../../output/sfdc: ") or '../../output/sfdc')
110
- destination_filepath = Path(input("Enter the core filepath. Default: /Users/scarraway/repositories/salesforce/core/core-public/core: ") or '/Users/scarraway/repositories/salesforce/core/core-public/core')
170
+ async def main():
171
+ parser = argparse.ArgumentParser(description="The release script for LDS")
172
+ parser.add_argument("-o", "--outputDir", help="Path to the output directory generated by yarn build:core-artifacts")
173
+ parser.add_argument("-c", "--coreDir", help="Path to the target core directory")
174
+ args = parser.parse_args()
175
+
176
+ source_filepath = Path(args.outputDir or input("Enter the location of the LDS release artifact. Default: ./output: ") or './output').expanduser()
177
+ print("LDS Release artifact path:", source_filepath)
178
+ if not (source_filepath / 'sfdc').exists():
179
+ raise SystemExit(f"LDS release artifact directory({source_filepath}) does not seem to exist. Did you provide the correct path? Did you run yarn build:core-artifacts?")
180
+ destination_filepath = Path(args.coreDir or input("Enter the core filepath. Default: /opt/workspace/core-public/core: ") or '/opt/workspace/core-public/core').expanduser()
181
+ print("Destination filepath:", destination_filepath)
182
+ if not (destination_filepath / 'ui-force-components').exists():
183
+ raise SystemExit(f"Destination core directory does not seem to contain ui-force-components. Did you provide the correct path to your core directory?")
184
+ # Print the entered filepaths
111
185
 
112
- # Print the entered filepaths
113
- print("Source filepath:", source_filepath)
114
- print("Destination filepath:", destination_filepath)
186
+
187
+ useP4 = await usingPerforce(destination_filepath)
188
+ new_modules = await copy_release(source_filepath / 'sfdc', destination_filepath, useP4)
115
189
 
116
- new_modules = copy_release(source_filepath, destination_filepath)
190
+ if(len(new_modules) == 0):
191
+ print(f"No new modules detected")
192
+ return
193
+ else:
194
+ print(f"New modules added: {new_modules}")
195
+ await update_ownership_yml(destination_filepath, new_modules, useP4)
196
+ await update_lwc_workflow_test(destination_filepath, new_modules, useP4)
117
197
 
118
- print(f"New modules added: {new_modules}")
119
- update_ownership_yml(destination_filepath, new_modules)
120
- update_lwc_workflow_test(destination_filepath, new_modules)
198
+ asyncio.run(main())