SFDX: Setting role for "User User"

After what @Raul said in the comments, and with this known issue, it can be seen that there is a general issue with Salesforce SFDX scratch orgs and "Out of the Box" roles. The workaround I have used is to:

  1. pre-define a custom role as part of our meta data called "Automation"
  2. execute some Anonymous Apex from our Ant build

The Ant script target for point #2 is:

<target name="init-scratch-org-user" depends="sfdx, get-existing-alias">
    <echo output="${anon.apex.file}"><![CDATA[
        // Give the user the required permission set and role
        List<PermissionSet> sets = [SELECT Id FROM PermissionSet WHERE Name = 'Scratch_Org_User'];
        List<User> users = [SELECT Id FROM User WHERE Alias = 'UUser'];
        List<UserRole> roles = [SELECT Id FROM UserRole WHERE Name = 'Automation'];

        if (!sets.isEmpty() && !users.isEmpty() && !roles.isEmpty()) {
            PermissionSetAssignment assignment = new PermissionSetAssignment(
                    PermissionSetId = sets[0].Id,
                    AssigneeId = users[0].Id);
            users[0].UserRoleId = roles[0].Id;

            insert assignment;
            update users[0];
        }
        ]]>
    </echo>

    <exec executable="${sfdx}">
        <arg value="force:apex:execute"/>
        <arg value="-u${sfdx.alias}"/>
        <arg value="-f${anon.apex.file}"/>
    </exec>
</target>

Note that property "anon.apex.file" is generated from a tempfile, the sfdx target determines the CLI tool name as property "sfdx" and the get-existing-alias target obtains the target scratch org's alias in the "sfdx.alias" property.

This snippet of Anon Apex also happens to set a permission set assignment for the same user so we can have all the necessary CRUD and FLS settings initialized for that user as well.

UPDATE: I have subsequently discovered the SFDX CLI command that simplifies this setting up of the permission set assignment:

sfdx force:user:permset:assign -u alias -n PermissionSetName