UWPアプリをappinstallerを構成してGithub Pagesで配布する

# UWPアプリをappinstallerを構成してGithub Pages で配布する

## はじめに
私は，1年半ほどC#を使ったWindowsデスクトップアプリ開発を行ってきました．その中で，アプリインストーラーを構成したアプリのリリースに関するドキュメントや記事が少なく感じたので，自分なりのリリース方法を紹介したいと思います．
私もまだまだ初心者ですので，もっといい方法はあると思います．あくまで一例として参考になればと思います．

## 使用環境
Visual Studio 2022 Preview

## 今回やること
1. UWPのアプリをパッケージ化しAppPackages生成する

    1.1. UWPアプリにappinstaller構成ファイルを追加する
    1.2. UWPアプリをパッケージ化して，AppPackagesを生成する

2. AppPackagesをGithub Pagesにデプロイし，リリースページを作成する

    2.1. 生成されたAppPackagesをGithubにアップロードする
    2.2. static htmlの構成でGithub Pagesのセットアップをする．
    2.3. ワークフローを書き換える

## 1. UWPのアプリをパッケージ化しAppPackages生成する
UWPアプリを用意します．今回は，サンプルとして，ボタンをクリックするとカウントが1ずつ増えるだけのアプリを用意しました．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494604/c976bcac-2025-c87e-41b4-af6373ec2982.png)
サンプルアプリの画像

### 1.1. UWPアプリにappinstaller構成ファイルを追加する

ここから，appinstaller構成ファイルを追加していきます．
ソリューションエクスプローラーの，メインとなるプロジェクトを右クリックして「追加」から「新しい項目」を選択します．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494604/f388bb52-2f9d-b546-01f5-c45a715e3fef.png)
今回の場合，「SampleApp (Universal Windows)」を右クリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494604/e79dc2b1-729b-11fb-23c8-824919b64974.png)
メニューから「新しい項目」を選択

すると，「アプリ インストーラー」という項目があるので，これを選択して「追加」する．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494604/18340b5b-7ddc-0cda-e8f9-2f0ef96a0a09.png)

ここで追加される`Package.appinstaller`の中身は変える必要は無いが，`<UpdateSettings/>`の中身を変えることで，アップデートのタイミング等をいろいろ設定できる．
詳細は以下のリンクを参照.
https://learn.microsoft.com/ja-jp/uwp/schemas/appinstallerschema/element-update-settings

```xml:Package.appinstaller
<?xml version="1.0" encoding="utf-8"?>
<AppInstaller Uri="{AppInstallerUri}"
              Version="{Version}"
              xmlns="http://schemas.microsoft.com/appx/appinstaller/2017/2">

  <MainBundle Name="{Name}"
              Version="{Version}"
              Publisher="{Publisher}"
              Uri="{MainPackageUri}"/>

  <UpdateSettings>
    <OnLaunch HoursBetweenUpdateChecks="0"/>
  </UpdateSettings>

</AppInstaller>
```

### 1.2. UWPアプリをパッケージ化して，AppPackagesを生成する
**AppPackagesを生成する前に前準備**
リリースページを配置するためのgithubのリモートリポジトリを作成しておきましょう．今回は`SampleReleasePage`という名前で作成しておきました．
ここで作成する理由は，AppPackagesを生成する際に，配置するサイトのURLが必要になるためです．
今回はGithub Pagesを使用するため，サイトのURLは`https://<ユーザー名>.github.io/<リポジトリ名>/`となります．

**AppPackagesを生成する**
プロジェクトを右クリックして「公開」から「アプリパッケージの作成」を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494604/51398256-9a1b-88ea-b436-cf2e9e8e33bf.png)

「サイドローディング」を選択し，「次へ」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494604/2f9639fb-69d6-4881-43e4-bd09cbc61a1d.png)

署名をしないと配布ができないため，「作成」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494604/acbbd239-bb57-e140-2dce-ad425149e1e4.png)

発行者共通名を入力し，パスワードを設定して「OK」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494604/cacf1e6a-cf42-8f1a-2e60-1ca3012d1b2c.png)

現段階で証明書を信頼する必要性はありませんが，信頼するとインストールのテストがしやすいため，「信頼する」から証明書を信頼しておいた方がいいと思います．それが終わったら，「次へ」をクリックします．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494604/476b5c64-5bab-4820-eafe-60427a1b7832.png)

今回はビルド時間が長くなるため，x86アーキテクチャのみにチェックを入れて公開しますが，必要に応じてチェックを増やしても大丈夫です．
チェックを付けたら，「次へ」を選択
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494604/38641faa-9678-6480-c0cc-60b070bc1d29.png)

ここで，インストーラーの場所を公開予定のGithub PagesのURLにしましょう．URLを入力したら「作成」を選択して，しばらくすると，AppPackagesの生成が完了します．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494604/2e41c82a-e1be-b503-af3a-c5e1a71ac18b.png)

生成が完了すると，下の画面が表示されます．

![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494604/24599132-a40c-e48e-f541-5f071833a414.png)

これでAppPackagesの生成が完了です．では，AppPackagesの中身を見てみましょう．
プロジェクトを右クリックして，「エクスプローラーで開く」を選択すると，エクスプローラーの一番上にAppPackagesというフォルダが生成されているのが分かります．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494604/b343409b-d9d2-83aa-c399-2312922fa97a.png)

AppPackagesを開くと，`index.html`と`<アプリ名>.appinstaller`，`<アプリ名>_<バージョン>_Test`フォルダが生成されています．今回の場合だと，`index.html`,`SampleApp.appinstaller`,`SampleApp_1.0.0.0_Test`が生成されています．`index.html`はアプリインストーラーの起動やダウロードを行えるようになっているため，このAppPackagesの中身をGithub Pagesで静的Webアプリとしてデプロイすれば，アプリの配布が可能となります．しかし，`<アプリ名>_<バージョン>_Test`のフォルダはかなり容量があるので，このままstatic htmlテンプレートのyamlでCI/CDを組むと，TimeOutでデプロイが通らない場合が出てくるため，少し加筆する必要があります．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494604/1624e03c-9e8c-94c8-209a-c3614302ecc4.png)


## 2. AppPackagesをGithub Pagesにデプロイし，リリースページを作成する
### 2.1. 生成されたAppPackagesをGithubにアップロードする
エクスプローラーから，AppPackagesを右クリックし，「ターミナルで開く」を選択．
そこからは，コマンドラインでGithubにアップロードしましょう．

```powershell
git init
git add .
git commit -m "<commit message>"
git branch -M main
git remote add origin https://github.com/<UserName>/SampleReleasePage.git
git push -u origin main
```

### 2.2. static htmlの構成でGithub Pagesのセットアップをする．

リリースページのGithubのリポジトリから，「Settings」から，左のメニューにある「Pages」をクリック．

「Build and deployment」項目の，Sourceを「Github Actions」に設定し，「Static HTML」の「Configure」をクリックする．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494604/8c68d514-c347-9e09-ce62-a3afa50f56a3.png)

すると，yamlファイルの編集画面に入ります．このぐらいのサイズのアプリであれば，このままでもデプロイが可能かもしれませんが，アプリの容量が増えると，デプロイが通らなくなってくるので，このyamlファイルを編集していきます．

### ワークフローを書き換える
ではこのテンプレート書き換えていきます．
アプリの容量が大きすぎることが問題なので，`<アプリ名>_<バージョン>_Test`以下のファイルを圧縮して，軽くする処理を加えます．

```yaml:.github/workflows/static.yml
# Simple workflow for deploying static content to GitHub Pages
name: Deploy static content to Pages

on:
  # Runs on pushes targeting the default branch
  push:
    branches: ["main"]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
  contents: read
  pages: write
  id-token: write

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
  group: "pages"
  cancel-in-progress: false

jobs:
  # Single deploy job since we're just deploying
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Setup Pages
        uses: actions/configure-pages@v3

#---------------ここから-------------------
      - name: Compress files
        run: |
          for dir in SampleApp_*; do
            zip -r "%dir.zip" "$dir"
          done
      - name: Upload compressed files
        uses: actions/upload-artifact@v2
        with:
          name: compressed-files
          path: SampleApp_*/.zip
#----------------ここまで--------------------
# "SampleApp_*"を"<プロジェクト名>_*" に変更してください．

      - name: Upload artifact
        uses: actions/upload-pages-artifact@v2
        with:
          # Upload entire repository
          path: '.'
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v2

```
この処理を追加することで，`SampleApp_1.0.0.0_Test`以下のファイルを圧縮してアップロードしています．アプリのバージョンはリリース毎に変わるため，`SampleApp_*`という正規表現で指定しています．

このファイルをコミットし，Github Actionsタブに移動し，しばらく待つと，
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494604/206d66db-0e31-a300-9765-3e9cf6c6a31c.png)
ワークフローがすべて通っているので，デプロイ成功です！

## 動作確認

一度設定からSampleAppをアンインストールします．
開発環境のパッケージ化されてないアプリが既に存在していると，競合が起きて正常にインストールが出来なくなってしまいます．

![image3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494604/43719e1d-1a4d-f023-7a59-7ef31b27ccf1.png)

アンインストールが出来たら，デプロイしたGithub Pagesにアクセスして，インストールできるか確認しましょう．
「アプリを取得する」からインストールできます．

![image4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494604/97e530fc-7ff9-0745-9713-892bce5351bc.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494604/6dc7d1ea-d07c-bd7f-5a62-2e86e995d718.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494604/ca7d09ad-c19e-3280-4054-981a56fabb84.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494604/a6228996-70e7-9922-9f6a-85ce924f3ff9.png)

インストール完了！

もし，他人に配布する場合は，公開者証明書を持っていないため，アプリインストール時にエラーが発生します．そのため，「追加のリンク」から，「公開者証明書」をダウンロードして，信用する必要があります．

![image5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494604/0c40bb87-5f5e-6271-1324-796984aa3496.png)

以上でUWPアプリをappinstallerを構成して配布する手順は終わりです．AppPackagesにリリース用のhtmlファイルが生成されるので，これをデプロイしてしまえばすぐに配布可能です．しかし，配布用のパッケージが重たいので，少し工夫が必要をする必要があります．

少しでもこの記事が参考になれば幸いです．

参考記事
https://learn.microsoft.com/ja-jp/windows/application-management/sideload-apps-in-windows-10
https://learn.microsoft.com/ja-jp/windows/msix/package/packaging-uwp-apps
https://learn.microsoft.com/ja-jp/windows/msix/app-installer/web-install-azure