kurmann / videoschnitt

Teilautomatisierung und Verwaltung für privaten Videoschnitt – das Kraftwerk für Familienfilme
Apache License 2.0
0 stars 0 forks source link

Publish to Homebrew #226

Open kurmann opened 1 week ago

kurmann commented 1 week ago

Wie werden Abhängigkeiten in Homebrew organisiert, bspw. hat meine Anwendung eine Abhängigkeit von FFMmpeg? Ich gehe davon aus, es ist einfacher wenn meine Abhängigkeit selbst auch eine Homebrew-Formel hat.

Meine Domain ist übrigens kurmann.swiss (Swiss selbst ist die TLD, sie ist neu verfügbar). Meine Anwendung heisst "Kurmann Videoschnitt", aber du musst Kurmann in der URL nicht wiederholen.


Abhängigkeiten in Homebrew-Formulas werden mithilfe der depends_on-Direktive organisiert. Wenn deine Anwendung beispielsweise eine Abhängigkeit von ffmpeg hat, kannst du dies in deiner Homebrew-Formula angeben.

Hier ist ein vollständiges Beispiel für eine Homebrew-Formula für deine Anwendung "Kurmann Videoschnitt", inklusive der Abhängigkeit zu ffmpeg:

Beispiel-Formula: videoschnitt.rb

class Videoschnitt < Formula
  desc "Kurmann Videoschnitt Anwendung"
  homepage "https://kurmann.swiss"
  url "https://github.com/deinGithubBenutzername/Kurmann.Videoschnitt/releases/download/v0.15.0/Kurmann.Videoschnitt-macos.tar.gz"
  sha256 "NEUE_SHA256_SUMME"
  version "0.15.0"

  depends_on "ffmpeg"

  def install
    bin.install "Kurmann.Videoschnitt"
  end

  plist_options :startup => true

  def plist; <<~EOS
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>Label</key>
        <string>com.kurmannswiss.videoschnitt</string>
        <key>ProgramArguments</key>
        <array>
            <string>#{opt_bin}/Kurmann.Videoschnitt</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>KeepAlive</key>
        <true/>
        <key>StandardOutPath</key>
        <string>#{var}/log/kurmann_videoschnitt.log</string>
        <key>StandardErrorPath</key>
        <string>#{var}/log/kurmann_videoschnitt.log</string>
    </dict>
    </plist>
    EOS
  end

  test do
    system "#{bin}/Kurmann.Videoschnitt", "--version"
  end
end

Schritte zur Erstellung und Veröffentlichung der Formula

  1. Berechne die SHA256-Prüfsumme:

    • Lade das Kurmann.Videoschnitt-macos.tar.gz-Archiv herunter und berechne die Prüfsumme:
      shasum -a 256 Kurmann.Videoschnitt-macos.tar.gz
    • Ersetze NEUE_SHA256_SUMME im Formula-Skript durch die berechnete Prüfsumme.
  2. Erstelle das Homebrew-Tap-Repository:

    • Erstelle ein neues Repository auf GitHub namens homebrew-videoschnitt.
    • Füge die Datei videoschnitt.rb hinzu.
  3. Formula veröffentlichen:

    • Committe und pushe die videoschnitt.rb-Datei in dein homebrew-videoschnitt-Repository:
      git add videoschnitt.rb
      git commit -m "Add Kurmann Videoschnitt Formula"
      git push origin main

Benutzeranweisungen zur Installation

  1. Tap hinzufügen:

    • Benutzer müssen dein Homebrew-Tap zu ihrer Homebrew-Installation hinzufügen:
      brew tap deinGithubBenutzername/videoschnitt
  2. Anwendung installieren:

    • Danach können sie die Anwendung zusammen mit ihren Abhängigkeiten installieren:
      brew install videoschnitt
  3. Dienst starten:

    • Schließlich können sie den Dienst starten:
      brew services start videoschnitt

Übersicht der Homebrew-Befehle zur Verwaltung des Dienstes

Aktualisierung der Formula

Wenn du eine neue Version veröffentlichst, aktualisiere die URL und die SHA256-Prüfsumme in der Formula und pushe die Änderungen in dein Homebrew-Tap-Repository. Benutzer können dann einfach brew upgrade videoschnitt ausführen, um die neueste Version zu erhalten.

Mit diesen Schritten stellst du sicher, dass deine .NET-Anwendung und ihre Abhängigkeiten einfach über Homebrew installiert und verwaltet werden können.

kurmann commented 1 week ago

Natürlich! Hier ist der angepasste GitHub-Workflow, der deine Anwendung bei jedem veröffentlichten Release auf Homebrew publiziert:

GitHub Workflow für Homebrew Veröffentlichung

name: Publish to Homebrew

on:
  release:
    types: [published]
  workflow_dispatch:

jobs:
  build-and-publish:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup .NET
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '7.0.x'

      - name: Install dependencies
        run: dotnet restore src/Application/Application.csproj

      - name: Build
        run: dotnet build --configuration Release --no-restore src/Application/Application.csproj

      - name: Publish
        run: dotnet publish --configuration Release --self-contained -r osx-x64 --output ./publish src/Application/Application.csproj

      - name: Archive files
        run: tar -czvf Kurmann.Videoschnitt-macos.tar.gz -C ./publish .

      - name: Calculate SHA256
        id: sha256
        run: echo "sha256=$(sha256sum Kurmann.Videoschnitt-macos.tar.gz | awk '{print $1}')" >> $GITHUB_ENV

      - name: Create or update Homebrew Formula
        run: |
          FORMULA_REPO="deinGithubBenutzername/homebrew-videoschnitt"
          FORMULA_FILE="Formula/videoschnitt.rb"

          FORMULA_CONTENT=$(cat <<EOF
class Videoschnitt < Formula
  desc "Kurmann Videoschnitt Anwendung"
  homepage "https://kurmann.swiss"
  url "https://github.com/deinGithubBenutzername/Kurmann.Videoschnitt/releases/download/${{ github.event.release.tag_name }}/Kurmann.Videoschnitt-macos.tar.gz"
  sha256 "${{ env.sha256 }}"
  version "${{ github.event.release.tag_name }}"

  depends_on "ffmpeg"

  def install
    bin.install "Kurmann.Videoschnitt"
  end

  plist_options :startup => true

  def plist; <<~EOS
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>Label</key>
        <string>com.kurmannswiss.videoschnitt</string>
        <key>ProgramArguments</key>
        <array>
            <string>#{opt_bin}/Kurmann.Videoschnitt</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>KeepAlive</key>
        <true/>
        <key>StandardOutPath</key>
        <string>#{var}/log/kurmann_videoschnitt.log</string>
        <key>StandardErrorPath</key>
        <string>#{var}/log/kurmann_videoschnitt.log</string>
    </dict>
    </plist>
    EOS
  end

  test do
    system "#{bin}/Kurmann.Videoschnitt", "--version"
  end
end
EOF
          )

          echo "$FORMULA_CONTENT" > $FORMULA_FILE

          git clone "https://github.com/$FORMULA_REPO.git"
          cd homebrew-videoschnitt
          echo "$FORMULA_CONTENT" > $FORMULA_FILE
          git add $FORMULA_FILE
          git commit -m "Update Kurmann Videoschnitt Formula to version ${{ github.event.release.tag_name }}"
          git push
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Upload Release Asset
        uses: actions/upload-release-asset@v2
        with:
          upload_url: ${{ github.event.release.upload_url }}
          asset_path: Kurmann.Videoschnitt-macos.tar.gz
          asset_name: Kurmann.Videoschnitt-macos.tar.gz
          asset_content_type: application/gzip

Erklärung

  1. Trigger: Der Workflow wird bei jedem veröffentlichten Release und manuell (workflow_dispatch) ausgelöst.

  2. Build-Schritte:

    • Checkout repository: Klont das Repository.
    • Setup .NET: Installiert das .NET SDK.
    • Install dependencies: Führt dotnet restore aus, um die Abhängigkeiten zu installieren.
    • Build: Baut das Projekt in der Release-Konfiguration.
    • Publish: Veröffentlicht das Projekt für macOS und speichert die Ausgaben im ./publish-Verzeichnis.
    • Archive files: Archiviert die veröffentlichten Dateien als tar.gz für macOS.
  3. SHA256-Prüfsumme berechnen:

    • Berechnet die SHA256-Prüfsumme des Archivs und speichert sie in einer Umgebungsvariable.
  4. Homebrew Formula erstellen oder aktualisieren:

    • Klont das Homebrew-Tap-Repository.
    • Erstellt oder aktualisiert die Homebrew-Formula-Datei mit den neuen URL- und SHA256-Prüfsummenwerten.
    • Commitet und pusht die Änderungen in das Homebrew-Tap-Repository.
  5. Release-Artefakt hochladen:

    • Lädt das Archiv als Release-Artefakt auf GitHub hoch.

GitHub Secrets

Stelle sicher, dass du die notwendigen Secrets (GITHUB_TOKEN) in deinem Repository konfigurierst, um auf dein Homebrew-Tap-Repository zugreifen und Änderungen pushen zu können.

Mit diesem Workflow kannst du sicherstellen, dass deine .NET-Anwendung bei jedem veröffentlichten Release automatisch auf Homebrew aktualisiert wird, und Benutzer können einfach mit brew upgrade auf die neueste Version aktualisieren.

kurmann commented 1 week ago

(...)

Das ist doch grossartig. Das heisst, ich könnte bereits während der Entwicklungszeit diese config anlegen und auch gleich benutzen. Wenn dann der Homebrew später in der Entwicklung dazukommt, dann kann ich die Datei einfach weiterbenutzen. Homebrew sollte allerdings bei der Installation und Upgrade die Datei nicht überschreiben


Genau, das ist eine großartige Vorgehensweise! Wenn du bereits während der Entwicklungszeit die Konfigurationsdatei in deinem Application Support-Verzeichnis anlegst und verwendest, kannst du die gleiche Datei auch später in der Produktion weiterverwenden. Homebrew sollte so konfiguriert werden, dass es die Konfigurationsdatei bei Installation und Upgrade nicht überschreibt.

Hier sind die Schritte, um sicherzustellen, dass Homebrew die Konfigurationsdatei nicht überschreibt:

1. Erstelle und verwende die Konfigurationsdatei während der Entwicklungszeit

Erstelle die Konfigurationsdatei an der vorgesehenen Stelle, z.B. ~/Library/Application Support/kurmann_videoschnitt/config.json.

Beispiel: Konfigurationsdatei config.json

{
  "InfuseMediaLibrary": {
    "LibraryPath": "/path/to/library"
  }
}

2. Verwende die Konfigurationsdatei in deiner .NET-Anwendung

Verwende das Beispiel aus der vorherigen Antwort, um die Konfigurationsdatei in deiner .NET-Anwendung zu laden und zu verwenden.

3. Aktualisiere die Homebrew-Formula, um die Konfigurationsdatei nicht zu überschreiben

Aktualisiere die Formula so, dass sie die Konfigurationsdatei nur beim ersten Installieren kopiert und bei Upgrades intakt lässt.

Beispiel-Formula: videoschnitt.rb

class Videoschnitt < Formula
  desc "Kurmann Videoschnitt Anwendung"
  homepage "https://kurmann.swiss"
  url "https://github.com/deinGithubBenutzername/Kurmann.Videoschnitt/releases/download/v0.15.0/Kurmann.Videoschnitt-macos.tar.gz"
  sha256 "NEUE_SHA256_SUMME"
  version "0.15.0"

  depends_on "ffmpeg"

  def install
    bin.install "Kurmann.Videoschnitt"
    (prefix/"config").install "config.json"
  end

  plist_options :startup => true

  def plist; <<~EOS
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>Label</key>
        <string>com.kurmannswiss.videoschnitt</string>
        <key>ProgramArguments</key>
        <array>
            <string>#{opt_bin}/Kurmann.Videoschnitt</string>
            <string>--config</string>
            <string>#{ENV['HOME']}/Library/Application Support/kurmann_videoschnitt/config.json</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>KeepAlive</key>
        <true/>
        <key>StandardOutPath</key>
        <string>#{var}/log/kurmann_videoschnitt.log</string>
        <key>StandardErrorPath</key>
        <string>#{var}/log/kurmann_videoschnitt.log</string>
    </dict>
    </plist>
    EOS
  end

  def post_install
    config_dir = "#{ENV['HOME']}/Library/Application Support/kurmann_videoschnitt"
    config_file = "#{config_dir}/config.json"
    mkdir_p config_dir
    cp "#{prefix}/config/config.json", config_dir unless File.exist?(config_file)
  end

  test do
    system "#{bin}/Kurmann.Videoschnitt", "--version"
  end
end

4. Sicherstellen, dass die Konfigurationsdatei bei Upgrades nicht überschrieben wird

Der post_install-Schritt in der Formula sorgt dafür, dass die Konfigurationsdatei nur kopiert wird, wenn sie noch nicht existiert. Dies stellt sicher, dass bestehende Konfigurationsdateien bei Upgrades nicht überschrieben werden.

Beispiel für den GitHub Workflow

Hier ist der GitHub Workflow, der sicherstellt, dass die Anwendung bei jedem veröffentlichten Release auf Homebrew publiziert wird, ohne die Konfigurationsdatei zu überschreiben:

name: Publish to Homebrew

on:
  release:
    types: [published]
  workflow_dispatch:

jobs:
  build-and-publish:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup .NET
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '7.0.x'

      - name: Install dependencies
        run: dotnet restore src/Application/Application.csproj

      - name: Build
        run: dotnet build --configuration Release --no-restore src/Application/Application.csproj

      - name: Publish
        run: dotnet publish --configuration Release --self-contained -r osx-x64 --output ./publish src/Application/Application.csproj

      - name: Archive files
        run: tar -czvf Kurmann.Videoschnitt-macos.tar.gz -C ./publish .

      - name: Calculate SHA256
        id: sha256
        run: echo "sha256=$(sha256sum Kurmann.Videoschnitt-macos.tar.gz | awk '{print $1}')" >> $GITHUB_ENV

      - name: Create or update Homebrew Formula
        run: |
          FORMULA_REPO="deinGithubBenutzername/homebrew-videoschnitt"
          FORMULA_FILE="Formula/videoschnitt.rb"

          FORMULA_CONTENT=$(cat <<EOF
class Videoschnitt < Formula
  desc "Kurmann Videoschnitt Anwendung"
  homepage "https://kurmann.swiss"
  url "https://github.com/deinGithubBenutzername/Kurmann.Videoschnitt/releases/download/${{ github.event.release.tag_name }}/Kurmann.Videoschnitt-macos.tar.gz"
  sha256 "${{ env.sha256 }}"
  version "${{ github.event.release.tag_name }}"

  depends_on "ffmpeg"

  def install
    bin.install "Kurmann.Videoschnitt"
    (prefix/"config").install "config.json"
  end

  plist_options :startup => true

  def plist; <<~EOS
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>Label</key>
        <string>com.kurmannswiss.videoschnitt</string>
        <key>ProgramArguments</key>
        <array>
            <string>#{opt_bin}/Kurmann.Videoschnitt</string>
            <string>--config</string>
            <string>#{ENV['HOME']}/Library/Application Support/kurmann_videoschnitt/config.json</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>KeepAlive</key>
        <true/>
        <key>StandardOutPath</key>
        <string>#{var}/log/kurmann_videoschnitt.log</string>
        <key>StandardErrorPath</key>
        <string>#{var}/log/kurmann_videoschnitt.log</string>
    </dict>
    </plist>
    EOS
  end

  def post_install
    config_dir = "#{ENV['HOME']}/Library/Application Support/kurmann_videoschnitt"
    config_file = "#{config_dir}/config.json"
    mkdir_p config_dir
    cp "#{prefix}/config/config.json", config_dir unless File.exist?(config_file)
  end

  test do
    system "#{bin}/Kurmann.Videoschnitt", "--version"
  end
end
EOF
          )

          echo "$FORMULA_CONTENT" > $FORMULA_FILE

          git clone "https://github.com/$FORMULA_REPO.git"
          cd homebrew-videoschnitt
          echo "$FORMULA_CONTENT" > $FORMULA_FILE
          git add $FORMULA_FILE
          git commit -m "Update Kurmann Videoschnitt Formula to version ${{ github.event.release.tag_name }}"
          git push
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Upload Release Asset
        uses: actions/upload-release-asset@v2
        with:
          upload_url: ${{ github.event.release.upload_url }}
          asset_path: Kurmann.Videoschnitt-macos.tar.gz
          asset_name: Kurmann.Videoschnitt-macos.tar.gz
          asset_content_type: application/gzip

Mit diesen Schritten stellst du sicher, dass deine Konfigurationsdatei während der Entwicklung und nach der Installation über Homebrew verwendet wird, ohne dass sie bei Updates überschrieben wird.