Skip to content

Instantly share code, notes, and snippets.

@amphro
Created May 5, 2017 21:17
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save amphro/aee7f366f2512702cb47bfb35150ce9d to your computer and use it in GitHub Desktop.
Save amphro/aee7f366f2512702cb47bfb35150ce9d to your computer and use it in GitHub Desktop.
Push RecordTypes and Data using SFDX
### Setup Import File and Permission Set
# Step 1. Export the RecordTypes
-> sfdx force:data:tree:export -q "SELECT ID, Name, DeveloperName, SobjectType FROM RecordType" -o data
Wrote 1 records to data/RecordType.json
# Here is what the export might look like
-> more data/RecordType.json
{
"records": [
{
"attributes": {
"type": "RecordType",
"referenceId": "RecordTypeRef1"
},
"Name": "MyType",
"SobjectType": "Account"
}
]
}
# Step 2. Export the Objects
-> sfdx force:data:tree:export -q "SELECT ID, Name FROM Account WHERE RecordType.Name = 'MyType'" -o data/
Wrote 1 records to data/Accounts.json
# Here is what the export looks like.
-> more data/Accounts.json
{
"records": [
{
"attributes": {
"type": "Account",
"referenceId": "AccountRef1"
},
"Name": "Acme"
}
]
}
# Step 3. Put a place mark in the data file.
-> more data/Accounts.json | jq '.records[] |= .+ {"RecordTypeId" : "@RecordTypeRef1"}' | more > data/AccountsWithRecordTypes.json
# Step 4. RecordType.json and AccountsWithRecordTypes.json are files you want to check into source control.
# Step 5. If you don't have a permission set that gives access to your record type, create one and pull the source down, then check into source controll
### Set up a new scratch org - Assumes you have a perm set and data files as described above
# Step 1. Create scratch org
-> sfdx force:org:create -s -f <path to config file>
# Step 2. Import the RecordType - We need this before the perm set push
-> sfdx force:data:tree:import -f data/RecordType.json
# Step 3. Push source (which includes perm set)
-> sfdx force:source:push
# Step 4. Assign permission set
-> sfdx force:user:permset:assign -n <Name-of-your-permset>
# Step 5. Tricky tricky. Add the RecordType reference name to all the accounts.
# a. First test getting the ID
-> sfdx force:data:soql:query -q "SELECT ID FROM RecordType WHERE DeveloperName = 'Test'" --json | jq -r '.records[0].Id'
# b. Replace place mark with ID
-> sed -i -e "s/@RecordTypeRef1/`sfdx force:data:soql:query -q \"SELECT ID FROM RecordType WHERE DeveloperName = 'Test'\" --json | jq -r '.records[0].Id'`/g" data/AccountWithRecordTypes.json
# Here is what the new file looks like
-> more data/AccountWithRecordType.json
{
"records": [
{
"attributes": {
"type": "Account",
"referenceId": "AccountRef1"
},
"Name": "Acme",
"RecordTypeId": "012xx00000022t6AAA"
}
]
}
# Step 6. Now you are ready to import the data
-> sfdx force:data:tree:import -f data/AccountWithRecordType.json
@dcarroll
Copy link

Should we just pull down record types on all data plan exports?

@botzcowski
Copy link

botzcowski commented Jun 14, 2019

It's 2019 and Salesforce still has no support for this, so here's the Windows Power Shell version for steps 3 & 5.

Add the marker

Get-Content dx_unit_test_load_out\Accounts.json | C:\jq-win64 ".records[] |= .+ {`"RecordTypeId`" : `"@RecordTypeRef1`"}" | Out-File dx_unit_test_load_out\AccountsWithRecordTypes.json

Query for record type id and place in variable

$recordTypeId = sfdx force:data:soql:query -q "SELECT Id FROM RecordType WHERE DeveloperName = 'whatever' AND SobjectType='Account'" --json | C:\jq-win64 -r ".result.records[0].Id"

Replace marker with variable value & clean up variable

(Get-Content -path dx_unit_test_load_out\AccountsWithRecordTypes.json -Raw) -replace '@RecordTypeRef1', $recordTypeId | Set-Content -path dx_unit_test_load_out\Accounts.json | Remove-Variable recordTypeId

@CXCAlfo
Copy link

CXCAlfo commented Feb 4, 2020

Interested to know if there is an easier way to do this when you have many different record types?

I have 3 record types on contact, 4 on Account, 2 on opportunity, 3 on contracts etc.etc.

Each object has 5 to 7 records split across the different types.

Is it possibly to have a reference in the JSON that references another file so you don't need to do the replace part.

Thinking file would contains @refopprtid1 = Contractor_Contact_Recordtype (this being the Developer Name of a record type.

You then extract with the SOQL into another file and it looks up/returns the relevant ID from Contractor Record Type which is then referenced by its @reference in the JSON?

@bkwdesign
Copy link

Hi there, @botzcowski and @allpro -

As we approach 2022, if my Account sObject is supposed to support 3 RecordTypes - are these workaround techniques the only way to push source to my scratch org? It's one of the last things holding up my company's ability to do automated CI pipelines of our codebase

@amphro
Copy link
Author

amphro commented Jan 6, 2022

@bkwdesign I asked around and it sounds like there still isn't a good answer. You might want to look into the sfdmu plugin. It is a lot more advanced than the things I am doing in this script 5 years ago. You could even ask on that repo to see if anyone has experience using it for record types.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment