我能从私有的Github仓库中公开发布吗?

73

我有一个应用程序,它在私有Github存储库中,想知道是否可以将发布版本公开,以便该应用程序可以从Github自动更新而不是我们必须自己托管它。

此外,我想知道是否可能从部署的应用程序使用Github API检查新更新。


3
目前不可能在私人仓库中发布公共版本。是的,您可以使用API检查是否有新版本-使用版本API:https://developer.github.com/v3/repos/releases/。 - Ivan Zuzak
9
有什么新闻吗?这是一个五年前的问题,希望能够实现一个功能。 - Xexeo
5个回答

58
一个解决方法是创建一个公共存储库,包括:
  • 空提交(git commit --allow-empty
  • 每个提交都有标签
  • 每个标签都对应一个发布版本
  • 每个发布版本都有交付内容(您的私有应用程序二进制文件)
这样一来,您就有了一个专门用于发布托管的可见存储库,以及一个专门用于源代码开发的私有存储库。

1
我不明白的是,为什么我要给每个提交打标签?为什么我不能只做一个空提交并打标签呢?我可能想太多了,但如果我执行 rm -rf .git 然后初始化一个新的 git 并强制推送到新的 open 仓库,这样做有什么区别呢? - user1767754
2
为什么我不能只提交一个空的commit并打上标签呢?这是因为每个发布都需要创建一个(空或非空)的commit,因此需要为每个commit/release创建一个标签来关联发布。 - VonC
那方面有任何示例吗? - hamaney
@hamaney 不直接可见(因为涉及私人存储库) - VonC
通常我会上传到Github网站上。 - Harikrushna Patel

22

正如@VonC所提到的,我们必须为此创建第二个存储库。这并不是被禁止的,我已经在做了。通过Github workflows,我自动化了这个任务,我正在使用开发/主分支,所以每当我将任何东西推送到主分支时,一个新版本就会被构建并推送到公共“发布”存储库。

在我的具体用例中,我正在构建一个android apk,并通过非官方github api“hub”发布它。一些额外的好处是,您可以为外部问题和错误设置额外的问题跟踪器。

name: Master CI CD

# using checkout@v2 instead of v1 caus it needs further configuration

on:
  pull_request:
    types: [closed]

jobs:
  UnitTest:
    runs-on: ubuntu-latest
    if: github.event.pull_request.merged
    steps:
      - uses: actions/checkout@v2
      - name: make executable
        run: chmod +x gradlew
      - name: Unit tests
        run: |
          ./gradlew test
  IncrementVersionCode:
    needs: UnitTest
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: set up JDK 1.8
        uses: actions/setup-java@v1
        with:
          java-version: 1.8
      - name: make executable
        run: chmod +x gradlew
      - name: increment version
        run: ./gradlew incrementVersionCode
      - name: Push new version to master
        run: |
          git config --local user.email "workflow@bot.com"
          git config --local user.name "WorkflowBot"
          git commit -m "Increment Build version" -a
          # maybe better amend commits to avoid bot commits
  BuildArtifacts:
    needs: IncrementVersionCode
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: set up JDK 1.8
        uses: actions/setup-java@v1
        with:
          java-version: 1.8
      - name: make executable
        run: chmod +x gradlew
      - name: Build with Gradle
        run: ./gradlew build -x lint

      - name: Rename artifacts
        run: |
          cp app/build/outputs/apk/release/app-release.apk MyApp.apk
      - name: Upload Release
        uses: actions/upload-artifact@master
        with:
          name: Release Apk
          path: MyApp.apk
      - name: Upload Debug
        uses: actions/upload-artifact@master
        with:
          name: Debug Apk
          path: app/build/outputs/apk/debug/app-debug.apk

  # https://dev.to/ychescale9/running-android-emulators-on-ci-from-bitrise-io-to-github-actions-3j76
  E2ETest:
    needs: BuildArtifacts
    runs-on: macos-latest
    strategy:
      matrix:
        api-level: [21, 27]
        arch: [x86]
    steps:
      - name: checkout
        uses: actions/checkout@v2
      - name: Make gradlew executable
        run: chmod +x ./gradlew
      - name: run tests
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: ${{ matrix.api-level }}
          arch: ${{ matrix.arch }}
          script: ./gradlew connectedCheck

  Deploy:
    needs: E2ETest
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/master'
    steps:
      - uses: actions/checkout@v2 # Needed for gradle file to get version information
      - name: Get Hub
        run: |
          curl -fsSL https://github.com/github/hub/raw/master/script/get | bash -s 2.14.1
          cd bin
          chmod +x hub
          cd ..
      - name: Get Apk
        uses: actions/download-artifact@master
        with:
          name: Release Apk
      - name: Publish
        env:
          GITHUB_TOKEN: "${{ secrets.RELEASE_REPO_SECRET }}"
        run: |
          APP_NAME=MyApp
          VERSION_NAME=`grep -oP 'versionName "\K(.*?)(?=")' ./app/build.gradle`
          VERSION_CODE=`cat version.properties | grep "VERSION_CODE" | cut -d'=' -f2`
          FILENAME="${APP_NAME}-v${VERSION_NAME}-${VERSION_CODE}"
          TAG="v${VERSION_NAME}-${VERSION_CODE}"
          TAG="latest-master"
          echo $APP_NAME
          echo $VERSION_NAME
          echo $VERSION_CODE
          echo $FILENAME
          echo $TAG
          git clone https://github.com/MyUser/MyApp-Releases
          cd MyApp-Releases
          ./../bin/hub release delete "${TAG}" || echo "Failed deleting TAG: ${TAG}" # If release got lost catch error with message
          ./../bin/hub release create -a "../${APP_NAME}.apk" -m "Current Master Build: ${FILENAME}" -p "${TAG}"
  EvaluateCode:
    needs: Deploy
    runs-on: ubuntu-latest
    steps:
      - name: Get Hub
        run: |
          echo "TDOO: Run Jacoco for coverage, and other profiling tools"

16
2022年对于这个问题的答案更加简明易懂。您只需要使用预安装的gh CLI:
gh release create v0.0.1 foobar.zip -R https://github.com/your/repo-here

这个命令将在公共存储库中创建一个标签 v0.0.1 和一个附带本地文件 foobar.zip 的发布。您可以在任何私有存储库的 GitHub 操作中运行此命令。

-R 参数指向要在其上创建标签/发布的存储库。本地目录中会有 foobar.zip 文件。

重要的一点是: GITHUB_TOKEN 必须仍然设置为您希望发布的存储库的令牌!

完整示例:

- name: Publish
  env:
    GITHUB_TOKEN: "${{ secrets.RELEASE_REPO_SECRET }}"
  run: |
    gh release create v0.0.1 foobar.zip -R https://github.com/your/repo-here

如果你计划重新发布和覆盖现有版本,也可以使用 gh release delete 命令进行删除。使用 -d 标志创建草稿等发布。请查看文档。

我正在使用稍微更先进的方法,通过设置:

 shell: bash
 run: $GITHUB_ACTION_PATH/scripts/publish.sh

在文件scripts/publish.sh中:

#!/usr/bin/env node
const cp = require('child_process')
const fs = require('fs');
const path = require('path');

const APP_VERSION = JSON.parse(fs.readFileSync('package.json', { encoding: 'utf8' })).version
const TAG = `v${APP_VERSION}`

cp.execSync(`gh release create ${TAG} foobar.zip -R https://github.com/your/repo-name`, { stdio: 'inherit' })

这种方法使您能够使用Node.js或其他可用的编程语言,从项目管理文件(例如package.json)中提取版本,并自动确定正确的标记版本和名称。


1
谢谢@VonC - 哇,回复真快。从现在开始,我不会再称任何回复为“快速回复”,除非它比你的更快;) - kyr0
2
是的,但另一方面,总是在那里 ;) - VonC
发布版本中的资产实际存储在哪里?我有一个构建流水线,可以在私有仓库中标记发布版本。我想保留这个标记,但也要将发布版本的所有内容添加到公共仓库中。 - lmonninger
我觉得我遇到了和 @Imonninger 一样的问题。这个版本包含了来自公共分支的压缩源代码(但是是空的)。 - sam

1
以下的 GitHub Actions 工作流本质上自动化了 VonC 的回答中的步骤。它将一个仓库中的所有标签、发布和二进制文件克隆到另一个仓库中。
name: Clone
on:
  #Run every 12 hours
  schedule:
    - cron: "* */12 * * *"
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Run action
        uses: andrewthetechie/gha-clone-releases@v1.7.0
        with:
          token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
          src_repo: some-account/private-or-internal-repo
          dst_repo: some-other-account/public-repo
          copy_assets: true

使用on:参数来控制更新行为。上面的例子每12小时运行一次。另一个选项是设置on: push,以便在源代码创建新版本时立即将其克隆到目标位置。在这种情况下,工作流必须属于源代码仓库,以便可以检测到推送事件。
请注意,当使用细粒度令牌时,我需要为每个具有私有或内部可见性的仓库(源或目的地)添加PERSONAL_ACCESS_TOKEN作为密钥: enter image description here 理论上,可以使用本机提供的GITHUB_TOKEN来提供此访问权限,但GitHub尚未修复/添加该功能 - https://github.com/actions/setup-node/issues/49

干得好。当我写下我的答案时,GitHub Actions还不存在;)已点赞。 - VonC
1
当你从VonC那里得到+1时,试图装酷。 - jrbe228

0
一个简单的方法将私有仓库中的发布复制到公共仓库可能是使用Release & Assets Github Action,它可以:创建发布、上传发布资产并将发布复制到其他仓库。 然后,您可以使用常规的 electron-builder 更新程序支持公共仓库。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接