LoginSignup
1
0
お題は不問!Qiita Engineer Festa 2023で記事投稿!

スクラッチ組織定義ファイルのsettingsの正体は設定メタデータ

Posted at

スクラッチ組織定義ファイルにあるsettingsの意味がよく分かってなかった。
処理を追ってみると、settingsは設定メタデータがそのまま指定できるものだった。

設定 | メタデータ API 開発者ガイド | Salesforce Developers

例えばSalesforce DXプロジェクトを作成したときに作成されるスクラッチ組織定義ファイルのsettings:

config/project-scratch-def.json
  "settings": {
    "lightningExperienceSettings": {
      "enableS1DesktopEnabled": true
    },
    "mobileSettings": {
      "enableS1EncryptedStoragePref2": false
    }
  }

これは:

  • LightningExperienceSettingsメタデータのenableS1DesktopEnabled項目を有効化
  • MobileSettingsメタデータのenableS1EncryptedStoragePref2を無効化

という設定になる。

例えばもし管理者による代理ログインを有効化したい場合は、SecuritySettingsメタデータのenableAdminLoginAsAnyUser項目を有効化する。

config/project-scratch-def.json
  "settings": {
+   "securitySettings": {
+     "enableAdminLoginAsAnyUser": true
+   },
    "lightningExperienceSettings": {
      "enableS1DesktopEnabled": true
    },
    "mobileSettings": {
      "enableS1EncryptedStoragePref2": false
    }
  }

SecuritySettings | メタデータ API 開発者ガイド | Salesforce Developers

仕組み

settingsがどのようにスクラッチ組織に反映されるか処理の流れを追ってみる。

先に書くと大まかな流れは次のようになっていた:

  1. スクラッチ組織定義ファイルをもとにScratchOrgInfoオブジェクトレコードを作成(=スクラッチ組織作成)
  2. settingsから設定メタデータのXMLファイルを生成
  3. 設定メタデータのXMLファイルをスクラッチ組織にデプロイ

スクラッチ組織の作成はsf org create scratchコマンドで行うので、orgプラグインの実装を追う。

sf org create scratchコマンドの実体はこれ:

run()メソッドの中でscratchOrgCreateを呼んでる:

src/commands/org/create/scratch.ts
       const { username, scratchOrgInfo, authFields, warnings } = await scratchOrgCreate(createCommandOptions);

scratchOrgCreate@salesforce/coreパッケージ(sfdx-coreプロジェクト)にあるので、そっちを見ていく。

scratchOrgCreateを追っていくと次の処理がある:

src/org/scratchOrgCreate.ts
  const [scratchOrgInfoRequestResult, signupTargetLoginUrlConfig] = await Promise.all([
    // creates the scratch org info in the devhub
    requestScratchOrgCreation(hubOrg, scratchOrgInfo, settingsGenerator),
    getSignupTargetLoginUrl(),
  ]);

呼んでるrequestScratchOrgCreationScratchOrgInfoオブジェクトのレコードを作成する関数:

ScratchOrgInfoオブジェクトのレコードを作成するとスクラッチ組織が作成されるようになってる。
参考: Salesforce DXでAPIからスクラッチ組織を作成する - Qiita
スクラッチ組織ができたら後続の処理で設定をデプロイする:

src/org/scratchOrgCreate.ts
  const [authInfo] = await Promise.all([
    resolveUrl(scratchOrgAuthInfo),
    deploySettings(
      scratchOrg,
      settingsGenerator,
      apiversion ??
        configAggregator.getPropertyValue(OrgConfigProperties.ORG_API_VERSION) ??
        (await scratchOrg.retrieveMaxApiVersion()),
      // some of our "wait" time has already been used.  Calculate how much remains that we can spend on the deployment.
      Duration.milliseconds(wait.milliseconds - (Date.now() - startTimestamp))
    ),
  ]);

deploySettingsはここ:

src/org/scratchOrgInfoApi.ts
export const deploySettings = async (
  scratchOrg: Org,
  orgSettings: SettingsGenerator,
  apiVersion: string,
  timeout: Duration = Duration.minutes(10)
): Promise<void> => {
  const logger = await Logger.child('scratchOrgInfoApi-deploySettings');
  if (orgSettings.hasSettings()) {
    // deploy the settings to the newly created scratch org
    logger.debug(`deploying scratch org settings with apiVersion ${apiVersion}`);

    try {
      await orgSettings.createDeploy();
      await orgSettings.deploySettingsViaFolder(scratchOrg, apiVersion, timeout);
      // updating the revision num to zero during org:creation if source members are created during org:create.
      // This only happens for some specific scratch org definition file.
      await updateRevisionCounterToZero(scratchOrg);
      logger.trace('Settings deployed to org');
    } catch (error) {
      throw SfError.wrap(error as Error);
    }
  }
};

SettingGeneratorcreateDeploy()を呼んでる:

src/org/scratchOrgSettingsGenerator.ts
  public async createDeploy(): Promise<void> {
    const settingsDir = path.join(this.shapeDirName, 'settings');
    const objectsDir = path.join(this.shapeDirName, 'objects');
    await Promise.all([
      this.writeSettingsIfNeeded(settingsDir),
      this.writeObjectSettingsIfNeeded(objectsDir, this.allRecordTypes, this.allBusinessProcesses),
    ]);
  }

writeSettingsIfNeeded()はこちら:

src/org/scratchOrgSettingsGenerator.ts
  private async writeSettingsIfNeeded(settingsDir: string): Promise<void> {
    if (this.settingData) {
      await Promise.all(
        Object.entries(this.settingData).map(([item, value]) => {
          const typeName = upperFirst(item);
          const fname = typeName.replace('Settings', '');
          const fileContent = js2xmlparser.parse(typeName, value);
          return this.writer.addToStore(fileContent, path.join(settingsDir, fname + '.settings'));
        })
      );
    }
  }

js2xmlparser.parse()を呼んだりしてるのでXMLを作ってる様子。

createDeploy()のあとdeploySettingsViaFolder()メソッドを呼んで設定をスクラッチ組織にデプロイしている。

src/org/scratchOrgSettingsGenerator.ts
  public async deploySettingsViaFolder(
    scratchOrg: Org,
    apiVersion: string,
    timeout: Duration = Duration.minutes(10)
  ): Promise<void> {
    ...
    const connection = scratchOrg.getConnection();
    logger.debug(`deploying to apiVersion: ${apiVersion}`);
    connection.setApiVersion(apiVersion);
    const { id } = await connection.deploy(this.writer.buffer, {});
    ...

まとめ

settingsスクラッチ組織定義ファイルのドキュメントでも明確な説明がなくて、何を書けばいいかよくわからずググってそれらしい情報を探して試してを繰り返していた。
プラグインの実装を確認して正体が設定メタデータとはっきりしたので、これからはメタデータのドキュメントをもとにsettingsを記述できるようになった。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0