Salesforce DXとSalesforce CLIの入門練習ガイド


この記事ではsalesforce開発において基礎知識とも言えるSFDXとSalesforce CLIを簡単に学んでいきたいと思います。この記事に通じて分かるようになる内容が以下となります。

・Salesforce DXとSalesforce CLIとは
・Salesforce CLIが必要な開発環境とツール
・CLIコマンドを覚える
・メタデータのデプロイと取得
・クエリ/アップロードなどデータの操作
・CLIの自動化

この記事でかなりの一部内容がManish Choudhariさんのgithubを参照しています。
https://github.com/choudharymanish8585

## 1.Salesforce DXとSalesforce CLIとは
### 1-2.Salesforce DXとは
Salesforce DXは外部のリポジトリでアプリケーションを管理して標準化や自動化を進め、Salesforce開発の生産性や管理品質を向上するための機能の総称です。

Salesforce DX提供する機能(一部)
・Scratch Orgs(スクラッチ組織) : コマンドから自由に作成・破棄できるSalesforce組織。
・Salesforce CLI : Scratch Orgsや項目の作成などSalesforce組織の管理が実行できるコマンドツール

### 1-3.Salesforce CLIとは
Salesforce CLI は、 Salesforce 組織を利用した開発およびビルドの自動化のためのパワフルなコマンドラインインタフェース

Salesforce CLI提供する機能(一部)
・Salesforce組織に対して開発時に必要なコマンドのツール群
・スクラッチ組織とのソースコードの双方向同期
・組織の作成及び管理
・データのインポート及びエクスポート
・テストの作成及び実行
・パッケージの作成及びインストール

## 2.Salesforce CLIが必要な開発環境とツール
この記事で使った開発ツール及び開発環境を紹介します。
OS:Windows 11 Pro
エディタ:VSCode 
バージョン管理ツール:Git
その他:openssl(Win64 OpenSSL v1.1.1o)

### 2-1.VSCodeのダウンロードと拡張機能の実装
公式サイトはこちら（ https://code.visualstudio.com ）の URL です。では、さっそくこちらのボタンからダウンロードしていきましょう。
<!-- wp:image {"align":"center","id":127,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image aligncenter size-large"><img src="https://pclearnreport.weblike.jp/wp-content/uploads/2021/10/VSCodeダウンロード-1024x487.png" alt="" class="wp-image-127"/><figcaption> 公式サイト </figcaption></figure>
<!-- /wp:image -->

ダウンロードした後にインストールしましょう。
<!-- wp:image {"align":"center","id":41,"sizeSlug":"full","linkDestination":"none"} -->
<figure class="wp-block-image aligncenter size-full"><img src="https://pclearnreport.weblike.jp/wp-content/uploads/2021/02/image-3.png" alt="" class="wp-image-41"/><figcaption></figcaption></figure>
<!-- /wp:image -->
<!-- wp:image {"align":"center","id":42,"sizeSlug":"full","linkDestination":"none"} -->
<figure class="wp-block-image aligncenter size-full"><img src="https://pclearnreport.weblike.jp/wp-content/uploads/2021/02/image-4.png" alt="" class="wp-image-42"/></figure>
<!-- /wp:image -->

インストール完了後にActivity Barの拡張機能をクリックしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/4e1c8c83-4cbe-e584-32a4-2615f86c3273.png)
検索欄にsalesforceを入力し検索結果からSalesforce Extension Packをダウンロードしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/dc913073-fcd1-7961-e792-da12627e6f61.png)
これでVSCodeの設定が完了になりました。

### 2-2.gitのダウンロードとインストール

公式サイトはこちら（ https://gitforwindows.org/ ）の URL です。では、さっそくこちらのボタンからダウンロードしていきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/234235bd-c9f6-bc12-af61-6845ed3e4086.png)
ダウンロードした後にインストールしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/adbb9fcd-ec88-16e9-47da-25267dec7f09.png)
ここだけ二番目に変えて他の選択肢をそのままnextをおしましょう
### 2-3.git bashの起動
これからはgit bashでlinuxコマンドを操作するのでCortanaの検索窓にgit bashと入力して検索すると出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/8f007971-79cb-5d0c-4ea7-cdb4ca9e210c.png)
起動して確かめるましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/d255b989-bf52-2cf8-8439-ddcf6927b0ea.png)
無事に起動しました。

### 2-4.opensslのダウンロードとインストール
salesforce CLIの自動化にはopensslが必要なため公式サイト(https://slproweb.com/products/Win32OpenSSL.html) からダウンロードしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/9e2628dc-2808-6eff-1b94-4f6b0366e239.png)

Ver. 3.0系列とVer. 1.1.1系列それぞれのインストーラーが公式から用意されている。前者は2021年にメジャーバージョンアップした最新版で、今は採用しているプラットフォームはまた多くないため1.1.1系列をおすすめします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/4de1c0c2-679b-3b4f-aec5-aac4b3e614d1.png)
ダウンロードした後にインストールしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/6cb1b6e5-bca0-a5ef-c6df-2265de217861.png) 

## 3.Salesforce CLIの準備
開発環境や開発ツールなどを整えました、いよいよSalesforce CLI本体の準備に入ります。
### 3-1.Salesforce CLIのダウンロードとインストール
Salesforce CLIを公式（ https://developer.salesforce.com/ja/tools/sfdxcli )からダウンロードしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/178a97d1-9fb0-4f85-4107-8d46bc93b336.png)

ダウンロードした後にインストールしましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/1a066051-cd84-1a0b-1e2a-5d70c43861f9.png)
### 3-2.CLIコマンドを実行してみよう
フォルダの位置が分かるようにワークスペースのフォルダを作成しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/62107c98-8e41-6e2f-deea-68d0ac1635d9.png)

VSCodeを起動してフォルダーを開くをクリックしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/b0022719-0c04-1e6b-1c88-6b317f1948fa.png)
先ほど作成したフォルダーを選択しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/f0336989-a1ef-8def-296e-cedd36276f55.png)
フォルダーを開いた後にVSCodeのステータスバーのエラーとバグの表示をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/67794f30-2a91-3ebd-00d8-97a70e88af53.png)
クリックしてターミナルに切り替える
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/971bbafe-bb7d-575c-2ace-18f3dcdedbe8.png)

+隣の↓をクリックしてgit bashに切り替える

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/164af2e0-ea30-db01-0efd-ce8a899da789.png)
最初のCLIコマンドsfdx commandsを入力してください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/a1f60915-7a47-8645-14bc-626db7b78c7f.png)
CLIコマンド一覧が表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/77eb5501-9940-90d2-0372-3ad6bb10dc79.png)

### 3-3.CLIコマンドの構成
CLIコマンドはNamespace,Topic,Subtopic,Commandこの四つの部分で構築されている。
![command.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/2829a638-f5d6-7955-11e9-ab1a20e31c75.png)
#### 3-3-1.Namespaceについて
CLIコマンドはNamespaceで始まり基本的にforceで書く
#### 3-3-2.Topicについて
Namespaceの次の部分がTopic、これはApexやvisulaforceなど命令対象をしてする
#### 3-3-3.Subtopicについて
Topicの次の部分はSubtopic、これは指示している対象のより具体的な部分を指している(例：page,doc)
#### 3-3-4.Commandについて
最後の部分がCommand、具体的な命令を行う部分(例：create,delete)
#### 3-3-5.CLIコマンドの操作関連一覧
CLIコマンドの操作関連一覧のドキュメントを見るには命令の最後に--help
以下が例とする
``` 
sfdx force:user:list --help
```
実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/5205c6c1-a6eb-3215-53de-a4e04cb722b5.png)

## 4.SFDX プロジェクトについて
ここからはCLIコマンドを使うSFDXプロジェクト作成と関連作業するためのSalesforce組織の権限セットについて解説します。

### 4-1.SFDX プロジェクトの作成

作成命令のオプションについて調べよう
```
sfdx force:project:create --help
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/1414e569-65c2-a7d0-4ed3-6bec85221ca3.png)

・-d フォルダーに作成したファイルを保存
・-n プロジェクト名を決める
・-p デフォルトパッケージのデレクトリ
・-s プロジェクト関連のnamespace
・-t プロジェクト作成にデフォルトテンプレートを使う
・-x 変更セット開発フォーマットのmanifestをjsonとして出力

さそっくプロジェクトを作ってみよう、manifestつきかつプロジェクト名をCLISessionとする
```
sfdx force:project:create -n CLISession -x
```
無事に生成出来ました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/645ee235-8447-c5e9-6575-c0bbdcf521c2.png)
manifestの内容を確認しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/5d0f2953-0690-2adc-a102-46f435f46d2d.png)

自動化sampleの準備として以下の内容と入れ替えしましょう。
```package.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<types>
    <name>CustomApplication</name>
    <members>Tree_Plantation</members>
  </types>
  <types>
    <name>ApexClass</name>
    <members>TreeListController</members>
    <members>TreeListControllerTest</members>
    <members>TreeLocationController</members>
  </types>
  <types>
    <name>FlexiPage</name>
    <members>Tree_Plantation</members>
    <members>Tree_Plantation_UtilityBar</members>
  </types>
  <types>
    <name>Layout</name>
    <members>City__c-City Layout</members>
    <members>Tree_Plantation__c-Tree Layout</members>
    <members>Tree__c-Tree Layout</members>
  </types>
  <types>
    <name>LightningComponentBundle</name>
    <members>pubsub</members>
    <members>treeCard</members>
    <members>treeList</members>
    <members>treeLocation</members>
    <members>treePlantationExplorer</members>
  </types>
  <types>
    <name>CustomObject</name>
    <members>City__c</members>
    <members>Tree_Plantation__c</members>
    <members>Tree__c</members>
  </types>
  <types>
    <name>CustomField</name>
    <members>City__c.Location__c</members>
    <members>City__c.Target__c</members>
    <members>City__c.Total_Trees__c</members>
    <members>Tree_Plantation__c.Age__c</members>
    <members>Tree_Plantation__c.Number_Of_Tree_Planted__c</members>
    <members>Tree_Plantation__c.Planted_In__c</members>
    <members>Tree_Plantation__c.Tree__c</members>
    <members>Tree__c.Benefit__c</members>
    <members>Tree__c.Picture__c</members>
  </types>
  <types>
    <name>ListView</name>
    <members>City__c.All</members>
    <members>Tree_Plantation__c.All</members>
    <members>Tree__c.All</members>
  </types>
  <types>
    <name>PermissionSet</name>
    <members>TreePlantation</members>
  </types>
  <types>
    <name>StaticResource</name>
    <members>treeimages</members>
  </types>
  <types>
    <name>CustomTab</name>
    <members>City__c</members>
    <members>Tree_Plantation</members>
    <members>Tree_Plantation__c</members>
    <members>Tree__c</members>
  </types>
  <version>46.0</version>
</Package>
```
次にconfigのproject-scratch-def.jsonを確認しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/3f511665-d748-e6db-cbdc-660f5f2f3f04.png)
変更して独自のスクラッチ組織定義ファイルを作成 。そして、"hasSampleData": true,を加えましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/6de92a0f-108f-ed9e-1930-189045e1a494.png)
これでデフォルト設定のようにサンプルデータ生成するようになりました。
### 4-2.salesforce組織の権限セット
ここからはsalesforce組織の権限セットを行うためにまずはログインをする。ログイン命令関連のオプションも調べよう
```
sfdx force:auth:web:login --help
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/cebb2a9c-e89b-6552-802d-bd9dbcfbe4a5.png)
・-a 認証済み組織に別称付ける
・-d 認証済み組織をスクラッチ組織のデフォルトdev hub組織にする
・-i OAuthクライアントID(consumer keyと呼ばれる場合もある)
・-r ログインURL指定
・-s　デフォルトユーザー名セット

組織名をCLICourseDevHub としてデフォルトユーザー名セットしてloginしましょう。
```
sfdx force:auth:web:login -a CLICourseDevHub -s
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/909cc434-47ed-8c3e-117f-f64a2a107c60.png)
ログイン画面が開いたらログインしましょう。成功しましたらブラウザを閉じても大丈夫です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/a9514f6e-c36a-4dbf-d389-afcd9a036f63.png)
.sfdxフォルダのsfdx-config.jsonにデフォルトユーザー名セットが成功したかを確かめましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/4a3ebf64-4fd5-be0e-2136-1d35d80473ed.png)
デフォルトDev Hubユーザー名もセットしましょう。
```
sfdx force:config:set defaultdevhubusername=CLICourseDevHub
```
無事に追加しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/83772e54-ddb9-7486-cd11-fd433c84df98.png)
Salesforce では、開発中に最も頻繁に接続する組織のデフォルトのユーザ名を設定することをお勧めします。この作業は、Dev Hub 組織の認証時かスクラッチ組織の作成時に行うのが最も簡単です。プロジェクトディレクトリからそれぞれ --setdefaultdevhubusername または --setdefaultusername パラメータを指定します。別名を作成して、ユーザ名により読みやすい名前を付けることもできます。組織に接続するすべての CLI コマンドでユーザ名または別名を区別せずに使用できます。

## 5.CLIコマンド使うメタデータの働きについて
Metadata は、すべての標準オブジェクトを表す sObject に類似しています。Metadata は、メタデータ API ですべてのコンポーネントと項目を表します。各コンポーネントを ID で識別するのではなく、各カスタムオブジェクトまたはカスタム項目には一意の fullName があります。この名前は、Salesforce ユーザインターフェースでカスタムオブジェクトやカスタム項目を作成するときのために、標準オブジェクト名とは異なるものにする必要があります。ここではCLIコマンドを使うメタデータの操作を解説します。
### 5-1."mdapi"topicを使うメタデータの取得
まず、メタデータの取得ため今回に使う"mdapi"topicのコマンドについて調べる
```
sfdx force:mdapi --help
```
force:mdapi:convert　メタデータをメタデータAPIフォーマットからソースフォーマットに切り替える
force:mdapi:deploy   メタデータAPIを使いメタデータを組織にデプロイする
force:mdapi:retrieve メタデータAPIを使いメタデータを組織から取得する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/adba1e77-1d97-2716-1199-d55c815b83fa.png)



実際に操作してみよう、先ずはCLISessionフォルダにmetadataフォルダを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/a24f485d-63fa-70fc-7c9f-c9b13cf6c16a.png)

次にmanifestとメタデータを取得しましょう。
```
sfdx force:mdapi:retrieve -k manifest/package.xml -r metadata/
```

-k コンポーネントのmanifestのファイルパスを取得
-r  取得ファイルのディレクトリ指定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/4ef1fbfc-087e-ed74-2db1-60ceac40479f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/84cd1ffe-0188-efd7-0474-4371886561af.png)
無事にzipを取得しました、解凍しましょう。デフォルトパッケージのディレクトリではなく、先ほど作成したmetadataフォルダにしてください。
```
 unzip metadata/unpackaged.zip -d metadata/
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/8df26353-9d2c-8094-ff28-9a28991db25f.png)


次にunpackagedの内容をforce-appに入れ替えよう
```
 sfdx force:mdapi:convert -r metadata/unpackaged -d force-app
```
-r rootディレクトリ指定
-d 出力先のディレクトリ指定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/fa5521e6-b787-3105-2163-28b2306f8b03.png)
metadataのclassesと同じものを確認できます。


### 5-2."source"topicを使うメタデータの取得
まず、先ほど"mdapi"topicで取得や生成した内容を削除しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/838e3c2b-8fc8-0f91-cb60-1335f834630c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/5ecca079-8c25-f7fd-0035-4c4b95194724.png)

次に、"source"topicのコマンドでmanifestを取得してみよう
```
sfdx force:source:retrieve -x manifest/package.xml 
```
-x 取得コンポーネントのmanifestを指定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/00a470ab-8f71-927c-aa8f-6710726bee6a.png)

無事にメタデータを取得したかを確認する
### 5-3.LWCを作成する
lightning web componentをCLIコマンドで作ってみよう
```
sfdx force:lightning:component:create -n newTreePlantation -d force-app/main/default/lwc/ --type=lwc
```
-n コンポーネントの名前
-d 出力するディレクトリ
--type lightning componentのタイプ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/adbc8ebf-5f28-1c21-4170-0de068f487de.png)
名前がnewTreePlantation、ディレクトリがforce-app/main/default/lwc/のlightning web componentを作成しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/d862c0e3-0a52-fdee-0926-d723d301a006.png)
newTreePlantationの内容を以下に貼替ましょう。
```newTreePlantation.html
<template>
    <lightning-card>
        <lightning-button slot="actions" label="Record New Plantation" variant="brand" onclick={recordNewPlantation}>
        </lightning-button>
        <template if:true={showForm}>
            <lightning-record-form object-api-name="Tree_Plantation__c" 
                    record-id={recordId} 
                    layout-type="Full" 
                    mode={mode}
                    onsuccess={handleSuccess}>
            </lightning-record-form>
        </template>
    </lightning-card>
</template>
```

```newTreePlantation.js
import { LightningElement, track } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

export default class NewTreePlantation extends LightningElement {

     recordId;
     showForm = false;

    recordNewPlantation(){
        this.showForm = true;
        this.recordId = undefined;
    }

    handleSuccess(event) {
        const evt = new ShowToastEvent({
            title: "Plantation Recorded",
            message: "Record ID: " + event.detail.id,
            variant: "success"
        });
        this.dispatchEvent(evt);
    }

    get mode(){
        return this.recordId ? 'view' : 'edit';
    }
}
```

```newTreePlantation.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="newTreePlantation">
    <apiVersion>46.0</apiVersion>
    <isExposed>false</isExposed>
</LightningComponentBundle>
```
### 5-4"source"topicを使うメタデータのデプロイ
作成したLWCをCLIコマンドでデプロイしましょう。
```
 sfdx force:source:deploy --sourcepath force-app/main/default/lwc/
```
--sourcepath デプロイするソースのパス指定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/037473a8-d58c-7f48-eadc-718c5843db67.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/bdb6641a-d4d6-77c6-d6be-56cb80c79c96.png)

組織にログインしLightning コンポーネントを検索してnewTreeplantationがデプロイ成功したかを確認

### 5-5."source"topicを使うメタデータの削除
"source"topicのCLIコマンドでメタデータを削除しましょう。
```
sfdx force:source:delete --sourcepath force-app/main/default/lwc/newTreePlantation/
```
ローカルファイルのnewTreePlantationが削除されたかを確認する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/ff1d5ad6-72bc-e38c-a9ca-b1318c194179.png)
組織の方が削除されているかを確認してみよう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/9e04bae1-45d5-ab0a-3847-d65f95e2b5cf.png)

### 5-6."mdapi"topicを使うメタデータのデプロイ
デプロイ用のmetadataフォルダを作成しよう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/2e31a1b3-d2b1-a190-61d3-2df50849bf3b.png)
lwcの内容を入れよう
```
$ sfdx force:source:convert -r force-app/main/default/lwc -d metadata/
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/99a064d8-f390-8819-f41e-ba1f4d504a74.png)
"mdapi"topicのCLIコマンドでデプロイしよう
```
sfdx force:mdapi:deploy -d metadata/
```
実行した後にデプロイが成功したかを確認してみよう、先ずはDeploy IDをコピーしよう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/71c9d8a9-2b49-f6d0-af24-447a417fd043.png)
```
sfdx force:mdapi:deploy:report -i 君のDeploy ID
```
-i deployを確認するためのjob ID
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/4b4d9bdb-93de-aaa9-fd89-4248262ec797.png)

無事にデプロイしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/414ed6c4-eeab-17f4-0e50-3bcb774f66eb.png)

### 5-7.apexテストを一括に実行してみよう
CLIコマンドはapexテストすることができる
```
sfdx force:apex:test:run -l RunAllTestsInOrg -c -r=human
```
-l テストレベル
-c コードカバレッジ
-r　結果のタイプ

テスト結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/2d84387d-98ea-5925-37a5-fac757237559.png)

### 5-8.apexクラスを作成してみよう
CLIコマンドを使いapexクラスを生成してみよう
```
sfdx force:apex:class:create -n DemoclassTest -t=ApexUnitTest -d D:/sfdc/CLISession/force-app/main/default/classes
```
-n クラス名指定
-t テンプレートを決定
-d 生成したクラスの出力先

無事に生成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/aab38d41-ff47-c1c9-345f-a4205df037a7.png)

## 6.CLIコマンド使うsalesforceデータの働き
CLIコマンドでbulk,enterprise,treeなどのAPIのほかデータベースのSOQLも操作することができます。
```
sfdx force:data --help
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/16195377-cd69-3b2e-ac39-86c63be81c46.png)

### 6-1.salesforce クエリデータの使うサーチCLIコマンド
ここで解説するのがsalesforce クエリデータを使うコマンドを解説します。先ずはサーチクエリでTreeクラスのIdとNameを検索してみよう。
```
sfdx force:data:soql:query --query="SELECT Id,Name FROM Tree__c" -r human
```
（git bashが使えない場合はpowershellなどに切替して試してください。）

検索した項目が表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/682388ae-b39f-1a8c-9b5d-674fa228d232.png)

### 6-2.salesforce クエリデータをCLIコマンドで生成、更新、削除する
まず、CLIコマンドで新しい項目のデータを生成しましょう。Tree NameがBingo TreeでBenefitがDummy Valueの項目を生成してみよう
```
sfdx force:data:record:create -s "Tree__c" --values "Name='Ringo Tree' Benefit__c='Dummy Value'"
```
-s　作成したいレコードの指定

新しいレコードを生成しました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/94e33c2b-f053-0e05-4ce3-e9f915ae4303.png)
次に、レコードの更新をCLIコマンドで実行してみてください。
```
sfdx force:data:record:update -s "Tree__c" -i "a0C2v000019p2NREAY" -v "Name='Ringo Jum'"
```
-s 作成したいレコードの指定
-i レコードのid指定
-v 数値の指定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/d7eb0f6f-86c7-32ba-4b24-2b200b68abf1.png)

更新した後のTreeクラスのレコードをもう一度調べよう、無事に変更しました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/eac430a7-3fe6-e31d-fe06-3f999e8c9287.png)

最後にCLIコマンドでレコードを削除してみよう。
```
sfdx force:data:record:delete -s "Tree__c" -i "a0C2v000019p2NREAY"
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/d28d04e3-01e6-8350-9872-7ad4fcb76dde.png)

無事に削除しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/175638cd-5765-84fa-410e-7e0b3125ae8e.png)

## 6-4.Salesforceデータの出力
ここからはCLIコマンドでSalesforceデータのの出力を行います。まず、出力先のフォルダsample-dataを作成しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/1d9067a8-737a-c660-88f6-95424ccfb184.png)
salesforce組織にログインしクイック検索欄にスキーマビルダーを検索しよう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/cf8e1bc7-e6e8-134a-5e6d-73d79340625f.png)
スキーマビルダーに入り、選択解除をしましょう。
選択![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/5ab31396-0bca-5a43-7d32-b8a2304c0388.png)
その後、今回出力するCity、Tree、Tree_Plantationだけを保存
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/9d9fd0f8-0018-a5e7-9820-da9f2eeef106.png)

まず、はTree、Tree_Plantationをjson書式で出力してみよう。
```
 sfdx force:data:tree:export --json --query="SELECT Id, Name, Picture__c,Benefit__c,(SELECT Id, Number_Of_Tree_Planted__c, Age__c, Tree__c, Planted_In__c FROM Tree_Plantation__r) FROM Tree__c " --plan --outputdir .\sample-data\
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/de3a3a04-c514-f033-9a16-7add7ac5727e.png)
無事に出力出来ました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/bff38b94-c2e7-6a84-909e-a5061f36cd03.png)
次に、Cityをjsonで出力してみよう。
```
sfdx force:data:tree:export --json --query="SELECT Id, Name, Location__latitude__s,Location__longitude__s,Target__c FROM City__c" --plan --outputdir sample-data/
```
無事に出力出来ました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/647b0503-f56a-3233-a6f6-e7aa8d4326f0.png)

## 6-5.Salesforceデータの入力
ここからはCLIコマンドでSalesforceデータの入力を行います。まず、planのJSONファイルにCity関連の内容を加えましょう。
```Tree__c-Tree_Plantation__c-plan.json
[
    {
        "sobject": "Tree__c",
        "saveRefs": true,
        "resolveRefs": false,
        "files": [
            "Tree__cs.json"
        ]
    },
    {
        "sobject": "City__c",
        "saveRefs": true,
        "resolveRefs": false,
        "files": [
            "City__c.json"
        ]
    },
    {
        "sobject": "Tree_Plantation__c",
        "saveRefs": false,
        "resolveRefs": true,
        "files": [
            "Tree_Plantation__cs.json"
        ]
    }
  
]
```
次に、tree_PlantationにCityの関連項目を加えよう

```Tree_Plantation__cs.json
{
    "records": [
        {
            "attributes": {
                "type": "Tree_Plantation__c",
                "referenceId": "Tree_Plantation__cRef1"
            },
            "Number_Of_Tree_Planted__c": 3000,
            "Age__c": 23,
            "Tree__c": "@Tree__cRef2",
            "Planted_In__c" : "@City__cRef1"
        },
        {
            "attributes": {
                "type": "Tree_Plantation__c",
                "referenceId": "Tree_Plantation__cRef2"
            },
            "Number_Of_Tree_Planted__c": 3000,
            "Age__c": 3,
            "Tree__c": "@Tree__cRef2",
            "Planted_In__c" : "@City__cRef2"
        },
        {
            "attributes": {
                "type": "Tree_Plantation__c",
                "referenceId": "Tree_Plantation__cRef3"
            },
            "Number_Of_Tree_Planted__c": 760,
            "Age__c": 2,
            "Tree__c": "@Tree__cRef2",
            "Planted_In__c" : "@City__cRef3"
        },
        {
            "attributes": {
                "type": "Tree_Plantation__c",
                "referenceId": "Tree_Plantation__cRef4"
            },
            "Number_Of_Tree_Planted__c": 3000,
            "Age__c": 3,
            "Tree__c": "@Tree__cRef2",
            "Planted_In__c" : "@City__cRef4"
        },
        {
            "attributes": {
                "type": "Tree_Plantation__c",
                "referenceId": "Tree_Plantation__cRef5"
            },
            "Number_Of_Tree_Planted__c": 600,
            "Age__c": 3,
            "Tree__c": "@Tree__cRef1",
            "Planted_In__c" : "@City__cRef1"
        },
        {
            "attributes": {
                "type": "Tree_Plantation__c",
                "referenceId": "Tree_Plantation__cRef6"
            },
            "Number_Of_Tree_Planted__c": 130,
            "Age__c": 2,
            "Tree__c": "@Tree__cRef3",
            "Planted_In__c" : "@City__cRef3"
        },
        {
            "attributes": {
                "type": "Tree_Plantation__c",
                "referenceId": "Tree_Plantation__cRef7"
            },
            "Number_Of_Tree_Planted__c": 180,
            "Age__c": 2,
            "Tree__c": "@Tree__cRef4",
            "Planted_In__c" : "@City__cRef4"
        },
        {
            "attributes": {
                "type": "Tree_Plantation__c",
                "referenceId": "Tree_Plantation__cRef8"
            },
            "Number_Of_Tree_Planted__c": 1080,
            "Age__c": 4,
            "Tree__c": "@Tree__cRef5",
            "Planted_In__c" : "@City__cRef5"
        },
        {
            "attributes": {
                "type": "Tree_Plantation__c",
                "referenceId": "Tree_Plantation__cRef9"
            },
            "Number_Of_Tree_Planted__c": 3000,
            "Age__c": 3,
            "Tree__c": "@Tree__cRef6",
            "Planted_In__c" : "@City__cRef3"
        },
        {
            "attributes": {
                "type": "Tree_Plantation__c",
                "referenceId": "Tree_Plantation__cRef10"
            },
            "Number_Of_Tree_Planted__c": 3000,
            "Age__c": 23,
            "Tree__c": "@Tree__cRef7",
            "Planted_In__c" : "@City__cRef2"
        },
        {
            "attributes": {
                "type": "Tree_Plantation__c",
                "referenceId": "Tree_Plantation__cRef11"
            },
            "Number_Of_Tree_Planted__c": 180,
            "Age__c": 2,
            "Tree__c": "@Tree__cRef8",
            "Planted_In__c" : "@City__cRef1"
        },
        {
            "attributes": {
                "type": "Tree_Plantation__c",
                "referenceId": "Tree_Plantation__cRef12"
            },
            "Number_Of_Tree_Planted__c": 1080,
            "Age__c": 4,
            "Tree__c": "@Tree__cRef8",
            "Planted_In__c" : "@City__cRef3"
        },
        {
            "attributes": {
                "type": "Tree_Plantation__c",
                "referenceId": "Tree_Plantation__cRef13"
            },
            "Number_Of_Tree_Planted__c": 760,
            "Age__c": 2,
            "Tree__c": "@Tree__cRef7",
            "Planted_In__c" : "@City__cRef4"
        },
        {
            "attributes": {
                "type": "Tree_Plantation__c",
                "referenceId": "Tree_Plantation__cRef14"
            },
            "Number_Of_Tree_Planted__c": 600,
            "Age__c": 3,
            "Tree__c": "@Tree__cRef6",
            "Planted_In__c" : "@City__cRef4"
        },
        {
            "attributes": {
                "type": "Tree_Plantation__c",
                "referenceId": "Tree_Plantation__cRef15"
            },
            "Number_Of_Tree_Planted__c": 3000,
            "Age__c": 3,
            "Tree__c": "@Tree__cRef5",
            "Planted_In__c" : "@City__cRef3"
        },
        {
            "attributes": {
                "type": "Tree_Plantation__c",
                "referenceId": "Tree_Plantation__cRef16"
            },
            "Number_Of_Tree_Planted__c": 130,
            "Age__c": 2,
            "Tree__c": "@Tree__cRef4",
            "Planted_In__c" : "@City__cRef2"
        }
    ]
}
```

最後にインポートしましょう。
```
 sfdx force:data:tree:import -p .\sample-data\Tree__c-Tree_Plantation__c-plan.json
```

## 7.スクラッチ組織の働きについて
ここからCLIコマンドでスクラッチ組織関連の一連の操作を行います。まず、salesforce組織にログインしDev Hubを有効化にしましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/a9aa256b-00cc-412e-a1c6-438db6fb1876.png)
Dev Hub組織にログインしましょう。
```
sfdx force:auth:web:login -d
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/b25b6a80-ed77-3693-60eb-75e890d73916.png)

### 7-1.スクラッチ組織の作成
CLIコマンドでスクラッチ組織を作成してみよう
```
sfdx force:org:create -a CLICourseSC1 -d 30 -f config/project-scratch-def.json -s 
```
-a 組織別名を付ける
-d 有効日数指定　
-f 組織定義のファイルパス指定
-s デフォルトユーザー名指定

スクラッチ組織を作成しました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/3b885907-254a-6d07-f60f-9d50a378b296.png)

\CLISession\.sfdx\sfdx-config.jsonを開いてデフォルトユーザー名を変更したかを確認する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/0216ebbf-9f7e-5482-9f3b-937c6782934f.png)

### 7-2.GitHubのリポジトリをスクラッチ組織にpush

Manish Choudhariさんのgithubに入り、tree-plantationのgit HTTPSをコピーしましょう。
https://github.com/choudharymanish8585/tree-plantation

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/cf4e9177-b69e-a306-71c8-a1a34ebeaacb.png)

sfdcフォルダにcloneしましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/faf9ddee-2f67-be07-ed0d-7a86c50a3f74.png)

tree-plantationに入り組織にログインしてみよう。
```
cd tree-plantation\
```
。
```
sfdx force:auth:web:login -a CLISessionDevHub -d -s
```
 push用スクラッチ組織を作成してみよう
```
sfdx force:org:create -a CLICourseSC1 -d 30 -f config/project-scratch-def.json -s
```

組織にpushしてみよう
```
sfdx force:source:push
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/16ec5818-a987-0e00-d3a6-d066e327f000.png)
アプリケーションマネージャーを確認しよう
```
sfdx force:org:open
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/fb7afe68-2dfa-1ead-4464-18ca32bfe6e2.png)
権限を変更してアプリケーションランチャーに表示しよう
```
sfdx force:user:permset:assign -n TreePlantation
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/092c2434-4b69-3f73-79b3-ad7a8faadf11.png)

### 7-3.スクラッチ組織にデータをアップロードしよう
sample-dataの内容をアップロードしましょう。
```
sfdx force:data:tree:import -p .\sample-data\import-plan.json
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/9d4672c7-a4bf-9ea6-13bc-ef82fe2bd17f.png)
アプリを開いて確認してみよう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/90ae4d72-0d99-81a3-dd02-ef0d857bfd07.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/e70a0075-6953-1592-5e3e-00515388badd.png)

### 7-4.アプリを完成しよう
New Plantationタブを完成しよう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/37a86857-bf70-863a-bf52-45cc15c13eff.png)
sfdcフォルダでNewTreePlantationのコンポーネントを作成しましょう。
```
 sfdx force:lightning:component:create -n newTreePlatation --type lwc -d force-app/main/default/lwc/
```
newTreePlantationフォルダの内容を入れ替えよ
```newTreePlantation.html
<template>
    <lightning-card>
        <lightning-button slot="actions" label="Record New Plantation" variant="brand" onclick={recordNewPlantation}>
        </lightning-button>
        <template if:true={showForm}>
            <lightning-record-form object-api-name="Tree_Plantation__c" 
                    record-id={recordId} 
                    layout-type="Full" 
                    mode={mode}
                    onsuccess={handleSuccess}>
            </lightning-record-form>
        </template>
    </lightning-card>
</template>
```
```newTreePlantation.js
import { LightningElement, track } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

export default class NewTreePlantation extends LightningElement {

     recordId;
     showForm = false;

    recordNewPlantation(){
        this.showForm = true;
        this.recordId = undefined;
    }

    handleSuccess(event) {
        const evt = new ShowToastEvent({
            title: "Plantation Recorded",
            message: "Record ID: " + event.detail.id,
            variant: "success"
        });
        this.dispatchEvent(evt);
    }

    get mode(){
        return this.recordId ? 'view' : 'edit';
    }
}
```
```newTreePlantation.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="newTreePlantation">
    <apiVersion>46.0</apiVersion>
    <isExposed>false</isExposed>
</LightningComponentBundle>
```
treePlantationExplorerフォルダの
組織のオブジェクトマネージャーを開いて、Treeを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/89797433-5c11-7039-6a04-0c80932f37b6.png)
項目とリレーションを選択してBenefit
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/d7026275-7bff-a4ab-f88a-ee8bd8fd7015.png)
項目レベルセキュリティの設定を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/bb24b456-24d8-8d49-6078-567131412cb7.png)
参照可能を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/f7d07030-d1b5-7e20-2a16-b2845a9efffc.png)
同じくTreeオブジェクトのtreeとCityオブジェクトのLocation、Tree　PlantationオブジェクトのPlanted_In、Treeの項目レベルセキュリティを設定する

もう一度pushしましょう。
```
sfdx force:source:push
```
tree plantationをもう一度確認する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/4007fc19-0e19-2d35-a5ba-cb0e1da6d611.png)
ボタンをクリックしましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/4c2ac2ec-cdd0-118d-0392-966c5c5d7627.png)

完成したアプリをテストしましょう。
```
sfdx force:apex:test:run --testlevel RunAllTestsInOrg --codecoverage --resultformat human
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/f0b8af24-0748-79f5-2e35-7401c25fbf30.png)

## 8.開発ソースの流れ

ここではgithubなどバージョン管理ツールを用いて一通り開発の流れを紹介します。

### 8-1.ソース開発の流れ一覧

github上にDev、QA、UAT、MASTERなどのブランチを作成する。開発用のがDevブランチ、QAがグループ内のテスト用で、UATは検収テスト、MASTERは本番アップロード用
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/b916ee23-b0d4-bb91-a2c8-f3dddc7db329.png)

### 8-2.ソースの変更管理とスクラッチ組織へソースのpushとpull
現在開発中プロジェクトの変更を調べるにはこのCLIコマンドで調べる
```
force:source:status
```
ローカルの変更を調べるCLIコマンド
```
force:source:status -l
```

ここからはスクラッチ組織でTreePlantationの権限変更を行う、検索欄に権限を入力して権限セットを選択してTreePlantationを開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/41e34adc-60f4-69ec-832f-0a2c418b585b.png)
権限セットのオブジェクト設定を開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/4d0da9ca-ae37-5b85-6cd2-c61b785fb63c.png)
TreePlantationのオブジェクト設定を開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/2ab496d5-7b29-5b88-434c-ce776a342058.png)
編集をクリックして作成権限を取り消して保存しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/831c6344-07b8-24d5-3b5b-56cba1a16dc2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/aaf39e0a-06bd-d792-cc2f-60694938b8ab.png)
変更した後にリモートの変更を調べるCLIコマンド
```
sfdx force:source:status -r
```
スクラッチ組織権限の変更が確認取れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/2242b5e4-0084-1fef-47f9-8fbf8d5e5305.png)
ローカルの権限設定を確認しましょう。tree-plantation\force-app\main\default\permissionsets\
```TreePlantation.permissionset-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<PermissionSet xmlns="http://soap.sforce.com/2006/04/metadata">
    <applicationVisibilities>
        <application>Tree_Plantation</application>
        <visible>true</visible>
    </applicationVisibilities>
    <fieldPermissions>
        <editable>true</editable>
        <field>City__c.Location__c</field>
        <readable>true</readable>
    </fieldPermissions>
    <fieldPermissions>
        <editable>true</editable>
        <field>City__c.Target__c</field>
        <readable>true</readable>
    </fieldPermissions>
    <fieldPermissions>
        <editable>true</editable>
        <field>Tree_Plantation__c.Age__c</field>
        <readable>true</readable>
    </fieldPermissions>
    <fieldPermissions>
        <editable>true</editable>
        <field>Tree_Plantation__c.Number_Of_Tree_Planted__c</field>
        <readable>true</readable>
    </fieldPermissions>
    <fieldPermissions>
        <editable>true</editable>
        <field>Tree__c.Benefit__c</field>
        <readable>true</readable>
    </fieldPermissions>
    <fieldPermissions>
        <editable>true</editable>
        <field>Tree__c.Picture__c</field>
        <readable>true</readable>
    </fieldPermissions>
    <hasActivationRequired>false</hasActivationRequired>
    <label>TreePlantation</label>
    <objectPermissions>
        <allowCreate>true</allowCreate>
        <allowDelete>true</allowDelete>
        <allowEdit>true</allowEdit>
        <allowRead>true</allowRead>
        <modifyAllRecords>false</modifyAllRecords>
        <object>City__c</object>
        <viewAllRecords>false</viewAllRecords>
    </objectPermissions>
    <objectPermissions>
        <allowCreate>true</allowCreate>
        <allowDelete>true</allowDelete>
        <allowEdit>true</allowEdit>
        <allowRead>true</allowRead>
        <modifyAllRecords>false</modifyAllRecords>
        <object>Tree_Plantation__c</object>
        <viewAllRecords>false</viewAllRecords>
    </objectPermissions>
    <objectPermissions>
        <allowCreate>true</allowCreate>
        <allowDelete>true</allowDelete>
        <allowEdit>true</allowEdit>
        <allowRead>true</allowRead>
        <modifyAllRecords>false</modifyAllRecords>
        <object>Tree__c</object>
        <viewAllRecords>false</viewAllRecords>
    </objectPermissions>
    <tabSettings>
        <tab>City__c</tab>
        <visibility>Visible</visibility>
    </tabSettings>
    <tabSettings>
        <tab>Tree_Plantation</tab>
        <visibility>Visible</visibility>
    </tabSettings>
    <tabSettings>
        <tab>Tree_Plantation__c</tab>
        <visibility>Visible</visibility>
    </tabSettings>
    <tabSettings>
        <tab>Tree__c</tab>
        <visibility>Visible</visibility>
    </tabSettings>
</PermissionSet>

```
TreePlantationのオブジェクト権限が変更前の状態である
```
 <objectPermissions>
        <allowCreate>true</allowCreate>
        <allowDelete>true</allowDelete>
        <allowEdit>true</allowEdit>
        <allowRead>true</allowRead>
        <modifyAllRecords>false</modifyAllRecords>
        <object>Tree_Plantation__c</object>
        <viewAllRecords>false</viewAllRecords>
    </objectPermissions>
```
スクラッチ組織のメタデータをCLIコマンドでpullしてみよう。
```
sfdx force:source:pull
```
ローカルのTreePlantationの権限設定がスクラッチ組織方と同じになりました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/6750b2e9-081b-82ce-c995-e7dc7b53a75b.png)
ローカルのTreePlantationの権限設定を変更してpushしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/68a39827-2709-f22e-b589-f9e24c87dc9c.png)
```
sfdx force:source:push
```
無事に変更しました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/7c475498-485c-913e-7a0c-cad7f46e17ef.png)

## 9.Cliコマンドの自動化
ここではCLIコマンドの自動化を実現する
### 9-1.SSL証明書を作成しましょう
まず、SFDCフォルダにassetsフォルダを作成しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/4d07559f-b78f-3754-cd45-ca391fd88ee9.png)
次に、サーバーパスキーを作成しましょう
```
openssl genrsa -passout pass:x -out server.pass.key 2048
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/70873658-429c-49ef-ba25-35397a7e76f2.png)
更に、サーバーキーを作成しましょう
```
openssl rsa -passin pass:x -in server.pass.key -out server.key
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/9cda462d-a4c7-2c4f-8902-15c68d55787b.png)
そして、に証明書を作成しましょう,パスワードの入力なしで
```
 openssl req -new -key server.key -out server.csr
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/37aeca97-4e34-d063-874f-c4438b7b61d7.png)
最後に証明書を作成しましょう
```
openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/4a27ec1d-3d88-e12a-3da7-f839247af2d3.png)
 
### 9-2.接続アプリを作成
まず、アプリケーションマネージャーを検索し新規接続アプリケーションをクリックしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/fa8529a0-be76-2a86-a00c-a1a998b84309.png)
次に、新規接続アプリの基本情報の接続アプリケーション名、API 参照名、取引先責任者 メールを選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/82755e65-93e5-aa17-3ed2-c21ccdd7c0f6.png)
更に、API (OAuth 設定の有効化)、デジタル署名を使用、Web サーバフローの秘密が必要、更新トークンフローの秘密が必要に全部チェック入れよう、コールバック URLにhttp://localhost:1717/OauthRedirect と入力して、選択ファイルはserver.ctr
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/a04684b6-6f3f-e5ac-40ff-dec7de682e7e.png)
決定ボタンを押しましょう、次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/3ce44686-2ac7-911e-f5f8-281908a00b1c.png)

作成完了したらManageを押しましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/0200ef5c-7c6e-1e24-e2d1-b1f4081bf0db.png)
ポリシーを編集を押しましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/a618e8a5-fdf6-91a9-de7f-3e6df5e3ea10.png)
承認されたユーザーを変更しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/bf98bd58-b74c-de98-a947-c7e617980add.png)
プロファイルを管理するをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/c9d9b7df-1ec2-72d8-f96b-d4d602b8cbc4.png)
システム管理者をチェック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/15f8e13a-af6f-38e1-fd0c-d37758008daa.png)

証明書とキーを使いアプリに接続しましょう。
```
sfdx force:auth:jwt:grant --clientid <コンシューマ鍵> --jwtkeyfile  <サーバーキーの位置> --username <ユーザー名> --setdefaultdevhubusername
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/b88abe78-a608-24e2-3ca3-3adaef060621.png)

### 9-3.CLI自動化
ここではshファイルを使い、CLIコマンドの自動化を実現する
```cli-session-automation.sh
# Set env/temp variable
printf "STEP 1: Setting up temp variable\n"
export DEV_HUB_USER_NAME=hu01@bin.com
export COSUMER_KEY=3MVG9wt4IL4O5wvK9Ej2ruY3EJIRfqLRu_YbEVMEUC4eAIxYa9exg067gxE1t78KtcaJUVHyOzDXreHVz_NBL
export SERVER_KEY_LOCATION="D:/sfdc/assets/server.key"
export SFDX_PROJECT_LOCATION="D:/sfdc"


printf "STEP 2: Moving in project folder $SFDX_PROJECT_LOCATION\n"
cd $SFDX_PROJECT_LOCATION

printf "STEP 3: Creating new directory $(date +'%Y%m%d')\n"
mkdir $(date +'%Y%m%d')
cd $(date +'%Y%m%d')

# cloning github repo
printf "STEP 4: Cloning github repo\n"
git clone https://github.com/MynameIsUseful/tree-plantation.git
cd tree-plantation
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/4448a3fb-d1f3-5c1c-33af-bb30f71730d6.png)
この記事で行ったその他操作も加えよう
```cli-session-automation.sh
# Set env/temp variable
printf "STEP 1: Setting up temp variable\n"
export DEV_HUB_USER_NAME=hu01@bin.com
export COSUMER_KEY=3MVG9wt4IL4O5wvK9Ej2ruY3EJIRfqLRu_YbEVMEUC4eAIxYa9exg067gxE1t78KtcaJUVHyOzDXreHVz_NBL
export SERVER_KEY_LOCATION="D:/sfdc/assets/server.key"
export SFDX_PROJECT_LOCATION="D:/sfdc"


printf "STEP 2: Moving in project folder $SFDX_PROJECT_LOCATION\n"
cd $SFDX_PROJECT_LOCATION

printf "STEP 3: Creating new directory $(date +'%Y%m%d')\n"
mkdir $(date +'%Y%m%d')
cd $(date +'%Y%m%d')

# cloning github repo
printf "STEP 4: Cloning github repo\n"
git clone https://github.com/choudharymanish8585/tree-plantation.git
cd tree-plantation

# authorize dev hub org
printf "STEP 5: Authorizing Dev Hub Org\n"
sfdx force:auth:jwt:grant --clientid $COSUMER_KEY --jwtkeyfile  "$SERVER_KEY_LOCATION" --username $DEV_HUB_USER_NAME --setdefaultdevhubusername --setalias CLISessionDevHub

# creating scratch org
printf "STEP 6: Creating scratch org\n"
 sfdx force:org:create  --setdefaultusername --definitionfile config/project-scratch-def.json --setalias $(date +'%Y%m%d') --wait 10 --durationdays 30

# pushing metadata to scracth org
printf "STEP 7: Pushing metadata to scratch org"
sfdx force:source:push

# assign permission set
printf "STEP 8: Assigning permission set"
sfdx force:user:permset:assign -n TreePlantation

# upload sample data to scratch org
printf "STEP 9: Uploading sample data"
sfdx force:data:tree:import --plan sample-data/import-plan.json

# opening scratch org
printf "STEP 10: Opening scratch org"
sfdx force:org:open
```
## 8.CLIコマンドの自動化のまとめ
この記事ではCLIコマンドの自動化を行うための環境準備、salesforce組織権限設定、よく使うCLIコマンドや開発の流れなどを紹介しました。
接続アプリケーションを作成し証明書を選択して一連のコマンドをshに書き込み自動的にアップロードや変更が実現可能になりました。