Skip to content
Back to skills

Claude Skills Electron Distribution Skill Md

ASecurity

Electronアプリケーションの配布・自動更新専門知識 📚 リソース参照: このスキルには以下のリソースが含まれています。 必要に応じて該当するリソースを参照してください: - `.claude/skills/electron-distribution/resources/auto-update.md`: 自動更新実装詳細 - `.claude/skills/electron-distribution/resources/release-channels.md`: リリースチャネル管理 - `.claude/skills/electron-distribution/resources/store-distribution.md`: ストア配布ガイド - `.claude/skills/electron-distribution/templates/update-server.ts`: 更新サーバーテンプレート - `.claude/skills/electron-distribution/scripts/release.sh`: リリーススクリプト 専門分野: - 自動...

  • 666 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added February 8, 2026
developmenttypescriptreactnodeexpressawsterraformgitapidevopssecurity

Works with

  • cli
  • api

Security analysis

A100/100

Scanned February 12, 2026

npx -y skills add majiayu000/claude-skill-registry --skill claude-skills-electron-distribution-skill-md --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Claude Skills Electron Distribution Skill Md?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Claude Skills Electron Distribution Skill Md
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/majiayu000-claude-skills-electron-distribution-skill-md/badge)](https://www.skillsdirectory.com/skills/majiayu000-claude-skills-electron-distribution-skill-md)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: .claude/skills/electron-distribution/SKILL.md
description: |
  Electronアプリケーションの配布・自動更新専門知識

  📚 リソース参照:
  このスキルには以下のリソースが含まれています。
  必要に応じて該当するリソースを参照してください:

  - `.claude/skills/electron-distribution/resources/auto-update.md`: 自動更新実装詳細
  - `.claude/skills/electron-distribution/resources/release-channels.md`: リリースチャネル管理
  - `.claude/skills/electron-distribution/resources/store-distribution.md`: ストア配布ガイド
  - `.claude/skills/electron-distribution/templates/update-server.ts`: 更新サーバーテンプレート
  - `.claude/skills/electron-distribution/scripts/release.sh`: リリーススクリプト

  専門分野:
  - 自動更新: electron-updater設定
  - リリース管理: バージョニング、チャネル
  - ストア配布: Mac App Store、Microsoft Store
  - アップデートサーバー: 自前・GitHub Releases

  使用タイミング:
  - 自動更新機能を実装する時
  - リリースフローを構築する時
  - アプリストアに配布する時
  - 更新サーバーを設定する時

version: 1.0.0
---

# .claude/skills/electron-distribution/SKILL.md

Electronアプリケーションの配布・自動更新専門知識

---

## 概要

### 目的

Electronアプリケーションを効率的に配布し、
シームレスな自動更新を提供する。

### 対象者

- Electronアプリ開発者
- DevOpsエンジニア
- リリースマネージャー

---

## 配布方法の選択

### 配布チャネル比較

| 方法                | メリット           | デメリット   | 推奨ケース       |
| ------------------- | ------------------ | ------------ | ---------------- |
| **GitHub Releases** | 無料、簡単         | 帯域制限あり | OSS、小規模      |
| **S3/CloudFront**   | 高速、スケーラブル | コスト       | 中〜大規模       |
| **Mac App Store**   | 信頼性、発見性     | 審査、制約   | macOSメイン      |
| **Microsoft Store** | 信頼性、自動更新   | 審査         | Windowsメイン    |
| **自前サーバー**    | 完全制御           | 運用負荷     | エンタープライズ |

---

## 自動更新(electron-updater)

### 基本設定

```yaml
# electron-builder.yml
publish:
  - provider: github
    owner: your-username
    repo: your-repo
    releaseType: release
```

### 更新サービス実装

```typescript
// main/services/updater.ts
import { autoUpdater, UpdateInfo } from "electron-updater";
import { app, BrowserWindow, dialog } from "electron";
import log from "electron-log";

// ログ設定
autoUpdater.logger = log;
log.transports.file.level = "info";

// 更新チェック設定
autoUpdater.autoDownload = false;
autoUpdater.autoInstallOnAppQuit = true;

export class UpdateService {
  private mainWindow: BrowserWindow | null = null;

  constructor(win: BrowserWindow) {
    this.mainWindow = win;
    this.setupEventListeners();
  }

  private setupEventListeners(): void {
    // 更新確認中
    autoUpdater.on("checking-for-update", () => {
      this.sendToRenderer("update-status", { status: "checking" });
    });

    // 更新あり
    autoUpdater.on("update-available", (info: UpdateInfo) => {
      this.sendToRenderer("update-status", {
        status: "available",
        version: info.version,
        releaseNotes: info.releaseNotes,
      });

      // ユーザーに確認
      dialog
        .showMessageBox(this.mainWindow!, {
          type: "info",
          title: "更新があります",
          message: `バージョン ${info.version} が利用可能です。ダウンロードしますか?`,
          buttons: ["後で", "ダウンロード"],
          defaultId: 1,
        })
        .then(({ response }) => {
          if (response === 1) {
            autoUpdater.downloadUpdate();
          }
        });
    });

    // 更新なし
    autoUpdater.on("update-not-available", () => {
      this.sendToRenderer("update-status", { status: "up-to-date" });
    });

    // ダウンロード進捗
    autoUpdater.on("download-progress", (progress) => {
      this.sendToRenderer("update-progress", {
        percent: progress.percent,
        bytesPerSecond: progress.bytesPerSecond,
        total: progress.total,
        transferred: progress.transferred,
      });
    });

    // ダウンロード完了
    autoUpdater.on("update-downloaded", (info: UpdateInfo) => {
      this.sendToRenderer("update-status", {
        status: "downloaded",
        version: info.version,
      });

      dialog
        .showMessageBox(this.mainWindow!, {
          type: "info",
          title: "更新の準備完了",
          message: "更新をインストールするにはアプリを再起動してください。",
          buttons: ["後で", "今すぐ再起動"],
          defaultId: 1,
        })
        .then(({ response }) => {
          if (response === 1) {
            autoUpdater.quitAndInstall(false, true);
          }
        });
    });

    // エラー
    autoUpdater.on("error", (error) => {
      log.error("Update error:", error);
      this.sendToRenderer("update-status", {
        status: "error",
        message: error.message,
      });
    });
  }

  private sendToRenderer(channel: string, data: unknown): void {
    this.mainWindow?.webContents.send(channel, data);
  }

  // 手動更新チェック
  async checkForUpdates(): Promise<void> {
    try {
      await autoUpdater.checkForUpdates();
    } catch (error) {
      log.error("Check for updates failed:", error);
    }
  }

  // ダウンロード開始
  downloadUpdate(): void {
    autoUpdater.downloadUpdate();
  }

  // インストール
  quitAndInstall(): void {
    autoUpdater.quitAndInstall(false, true);
  }
}

// メインプロセスで初期化
app.whenReady().then(() => {
  const mainWindow = createMainWindow();
  const updateService = new UpdateService(mainWindow);

  // 起動時に更新チェック(遅延)
  setTimeout(() => {
    updateService.checkForUpdates();
  }, 3000);

  // IPC登録
  ipcMain.handle("update:check", () => updateService.checkForUpdates());
  ipcMain.handle("update:download", () => updateService.downloadUpdate());
  ipcMain.handle("update:install", () => updateService.quitAndInstall());
});
```

### Renderer側UI

```tsx
// renderer/components/UpdateNotification.tsx
import { useEffect, useState } from "react";

interface UpdateStatus {
  status:
    | "checking"
    | "available"
    | "downloading"
    | "downloaded"
    | "up-to-date"
    | "error";
  version?: string;
  message?: string;
}

interface UpdateProgress {
  percent: number;
  bytesPerSecond: number;
  total: number;
  transferred: number;
}

export function UpdateNotification() {
  const [status, setStatus] = useState<UpdateStatus | null>(null);
  const [progress, setProgress] = useState<UpdateProgress | null>(null);

  useEffect(() => {
    const cleanupStatus = window.electronAPI.onUpdateStatus(setStatus);
    const cleanupProgress = window.electronAPI.onUpdateProgress(setProgress);

    return () => {
      cleanupStatus();
      cleanupProgress();
    };
  }, []);

  if (!status || status.status === "up-to-date") {
    return null;
  }

  return (
    <div className="update-notification">
      {status.status === "checking" && <p>更新を確認中...</p>}

      {status.status === "available" && (
        <div>
          <p>バージョン {status.version} が利用可能です</p>
          <button onClick={() => window.electronAPI.downloadUpdate()}>
            ダウンロード
          </button>
        </div>
      )}

      {status.status === "downloading" && progress && (
        <div>
          <p>ダウンロード中: {Math.round(progress.percent)}%</p>
          <progress value={progress.percent} max={100} />
        </div>
      )}

      {status.status === "downloaded" && (
        <div>
          <p>更新の準備完了</p>
          <button onClick={() => window.electronAPI.installUpdate()}>
            再起動してインストール
          </button>
        </div>
      )}

      {status.status === "error" && (
        <p className="error">更新エラー: {status.message}</p>
      )}
    </div>
  );
}
```

---

## リリースチャネル

### チャネル設定

```yaml
# electron-builder.yml
publish:
  - provider: github
    owner: your-username
    repo: your-repo
    channel: ${channel}
```

```typescript
// main/services/updater.ts
// チャネル設定
function setUpdateChannel(channel: "stable" | "beta" | "alpha"): void {
  autoUpdater.channel = channel;
  autoUpdater.allowPrerelease = channel !== "stable";
  autoUpdater.allowDowngrade = false;
}

// ユーザー設定から読み込み
const userSettings = store.get("updateChannel", "stable");
setUpdateChannel(userSettings);
```

### バージョニング戦略

```
# Semantic Versioning
stable:  1.0.0, 1.0.1, 1.1.0, 2.0.0
beta:    1.1.0-beta.1, 1.1.0-beta.2
alpha:   1.1.0-alpha.1, 2.0.0-alpha.1

# package.json
{
  "version": "1.1.0-beta.1"
}
```

---

## GitHub Releases配布

### electron-builder.yml

```yaml
publish:
  - provider: github
    owner: your-org
    repo: your-app
    releaseType: release # or draft, prerelease
    private: false
```

### リリースワークフロー

```yaml
# .github/workflows/release.yml
name: Release

on:
  push:
    tags:
      - "v*"

jobs:
  release:
    strategy:
      matrix:
        include:
          - os: macos-latest
            platform: mac
          - os: windows-latest
            platform: win
          - os: ubuntu-latest
            platform: linux

    runs-on: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "npm"

      - run: npm ci
      - run: npm run build

      - name: Publish
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          # macOS署名
          APPLE_ID: ${{ secrets.APPLE_ID }}
          APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
          CSC_LINK: ${{ secrets.MAC_CERTS }}
          CSC_KEY_PASSWORD: ${{ secrets.MAC_CERTS_PASSWORD }}
          # Windows署名
          WIN_CERT_FILE: ${{ secrets.WIN_CERT_FILE }}
          WIN_CERT_PASSWORD: ${{ secrets.WIN_CERT_PASSWORD }}
        run: npm run publish -- --${{ matrix.platform }}
```

---

## S3/CloudFront配布

### 設定

```yaml
# electron-builder.yml
publish:
  - provider: s3
    bucket: your-app-releases
    region: us-east-1
    acl: public-read
    path: /releases/${os}/${arch}
```

### CloudFront設定(Terraform例)

```hcl
resource "aws_cloudfront_distribution" "releases" {
  origin {
    domain_name = aws_s3_bucket.releases.bucket_regional_domain_name
    origin_id   = "S3-releases"
  }

  enabled = true

  default_cache_behavior {
    allowed_methods        = ["GET", "HEAD"]
    cached_methods         = ["GET", "HEAD"]
    target_origin_id       = "S3-releases"
    viewer_protocol_policy = "redirect-to-https"

    forwarded_values {
      query_string = false
      cookies {
        forward = "none"
      }
    }
  }

  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }

  viewer_certificate {
    cloudfront_default_certificate = true
  }
}
```

### カスタム更新サーバー

```typescript
// update-server/server.ts
import express from "express";
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";

const app = express();
const s3 = new S3Client({ region: "us-east-1" });

// 更新情報エンドポイント
app.get("/update/:platform/:version", async (req, res) => {
  const { platform, version } = req.params;

  try {
    // 最新バージョン取得
    const latestVersion = await getLatestVersion(platform);

    if (compareVersions(latestVersion, version) > 0) {
      res.json({
        version: latestVersion,
        files: await getDownloadUrls(platform, latestVersion),
        releaseDate: await getReleaseDate(latestVersion),
        releaseNotes: await getReleaseNotes(latestVersion),
      });
    } else {
      res.status(204).send();
    }
  } catch (error) {
    res.status(500).json({ error: "Failed to check updates" });
  }
});

// ダウンロードエンドポイント
app.get("/download/:platform/:version/:file", async (req, res) => {
  const { platform, version, file } = req.params;

  // 署名付きURL生成
  const signedUrl = await generateSignedUrl(
    `releases/${platform}/${version}/${file}`,
  );

  res.redirect(signedUrl);
});

app.listen(3000);
```

---

## Mac App Store配布

### 制約事項

| 機能                   | 通常配布         | MAS           |
| ---------------------- | ---------------- | ------------- |
| 自動更新               | electron-updater | App Store     |
| サンドボックス         | 任意             | 必須          |
| ハードニングランタイム | 推奨             | 必須          |
| 署名                   | Developer ID     | Mac App Store |
| ネイティブモジュール   | 可               | 制限あり      |

### electron-builder設定

```yaml
# electron-builder.yml
mas:
  target: mas

  hardenedRuntime: true
  gatekeeperAssess: false

  entitlements: build/entitlements.mas.plist
  entitlementsInherit: build/entitlements.mas.inherit.plist

  # MAS用署名
  identity: "3rd Party Mac Developer Application: Company (TEAM_ID)"

  # プロビジョニングプロファイル
  provisioningProfile: build/embedded.provisionprofile

masDev:
  identity: "Mac Developer: Your Name (XXXXXXXXXX)"
  provisioningProfile: build/embedded-dev.provisionprofile
```

```plist
<!-- build/entitlements.mas.plist -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.security.app-sandbox</key>
    <true/>
    <key>com.apple.security.network.client</key>
    <true/>
    <key>com.apple.security.files.user-selected.read-write</key>
    <true/>
</dict>
</plist>
```

---

## Microsoft Store配布

### AppX設定

```yaml
# electron-builder.yml
win:
  target:
    - target: appx
      arch:
        - x64
        - arm64

appx:
  applicationId: CompanyName.AppName
  displayName: My Electron App
  identityName: 12345CompanyName.AppName
  publisher: CN=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
  publisherDisplayName: Company Name
  languages:
    - ja-JP
    - en-US
  addAutoLaunchExtension: false
  showNameOnTiles: true
  backgroundColor: "#ffffff"
```

---

## リリースチェックリスト

### リリース前

- [ ] バージョン番号更新
- [ ] CHANGELOGの更新
- [ ] 全プラットフォームでテスト
- [ ] コード署名の確認
- [ ] 依存関係のセキュリティ監査
- [ ] リリースノート作成

### リリース後

- [ ] ダウンロードリンク確認
- [ ] 自動更新テスト
- [ ] インストールテスト(クリーン環境)
- [ ] アップグレードテスト(既存インストール)
- [ ] クラッシュレポート監視

---

## 関連リソース

### 詳細ドキュメント

- `resources/auto-update.md` - 自動更新詳細
- `resources/release-channels.md` - チャネル管理
- `resources/store-distribution.md` - ストア配布

### テンプレート・スクリプト

- `templates/update-server.ts` - 更新サーバー
- `scripts/release.sh` - リリーススクリプト

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.