eggbert
eggbert

Reputation: 3233

Can I make releases public from a private github repo?

I have an application which is in a private github repo, and am wondering if the releases could be made public so that the app can auto-update itself from github instead of us having to host it.

Additionally I'm wondering if it's possible to use the github api from the deployed app to check for new updates.

Upvotes: 81

Views: 39881

Answers (5)

jrbe228
jrbe228

Reputation: 578

The following GitHub Actions workflow essentially automates the steps in VonC's answer. It clones all tags + releases + binaries from one repo to another.

name: Clone
on:
  #Run every 12 hours
  schedule:
    - cron: "* */12 * * *"
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Run action
        uses: andrewthetechie/[email protected]
        with:
          token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
          src_repo: some-account/private-or-internal-repo
          dst_repo: some-other-account/public-repo
          copy_assets: true

Use the on: parameter to control update behavior. The above example runs every 12 hours. Another option could be setting on: push to immediately clone new releases from source to destination as soon as they are created. In that case, the workflow must belong to the source repo, so push events can be detected.

Note that when using a fine-grained token, I needed to add PERSONAL_ACCESS_TOKEN as a Secret for each repo (source or destination) with Private or Internal visibility: enter image description here

In theory the natively-available GITHUB_TOKEN could provide this access, but GitHub has yet to repair/add that feature - https://github.com/actions/setup-node/issues/49

Upvotes: 4

beorn
beorn

Reputation: 31

A simple way to duplicate releases from a private repo to a public one may be this Release & Assets Github Action which can: Create a release, upload release assets, and duplicate a release to other repository.

Then you can use the regular electron-builder updater's support for public repos.

Upvotes: 0

kyr0
kyr0

Reputation: 515

The 2022 answer to this question is even more straight-forward. You'd just need to use the pre-installed gh CLI:

gh release create v0.0.1 foobar.zip -R https://github.com/your/repo-here

This command will create a tag v0.0.1 and a release with the local file foobar.zip attached on the public repository. You can run this in the GitHub Action of any private repository.

The -R argument points to the repository you'd like to create a tag/release on. foobar.zip would be located in your local directory.

One thing is important here: GITHUB_TOKEN must still be set as the token of the repository you'd like to release on!

Full example:

- 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

If you're planning to re-release and override existing versions, there is gh release delete as well. The -d flag creates a release as a draft etc. pp. Please take a look at the docs.

I'm using a slightly more advanced approach by setting:

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

And in file 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' })

This approach enables you to be able to for example, use Node.js or any other programming language available, to extract a version from the project management file of choice (e.g. package.json) and automatically come up with the right tag version and name.

Upvotes: 24

Hatzen
Hatzen

Reputation: 437

As @VonC mentioned we have to create a second Repository for that. This is not prohibited and i am doing it already. With github workflows i automated this task, I'm using a develop / master branching, so always when I'm pushing anything to the master branch a new version is build and pushed to the public "Realease" Repo.

In my specific use case I'm building an android apk and releasing it via unoffical github api "hub". Some additional advantage of this is you can have an extra issue tracker for foreign issues and bugs.

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 "[email protected]"
          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"

Upvotes: 24

VonC
VonC

Reputation: 1323115

A workaround would be to create a public repo, composed of:

  • empty commits (git commit --allow-empty)
  • each commit tagged
  • each tag with a release
  • each release with the deliveries (the binaries of your private app)

That way, you have a visible repo dedicated for release hosting, and a private repos for source development.

Upvotes: 61

Related Questions