Skip to content
This repository was archived by the owner on Mar 4, 2021. It is now read-only.

How to prevent creating multiple releases when using a build matrix? #14

Open
nukeop opened this issue Oct 30, 2019 · 10 comments
Open

How to prevent creating multiple releases when using a build matrix? #14

nukeop opened this issue Oct 30, 2019 · 10 comments

Comments

@nukeop
Copy link

nukeop commented Oct 30, 2019

I have a matrix which results in 3 builds. Is there a way to ensure only the first one will draft a new release?

@kf6kjg
Copy link

kf6kjg commented Nov 15, 2019

There does not appear to be. And yes, it's quite annoying to clean up afterwards.

In my case I'm not using a matrix, I'm instead using one job per OS - this is because each OS requires a fair amount of unique operations. I'd still like it to somehow detect that there was a pre-existing release or draft for that tag and name and skip.

However I'm torn between two ways this could be done:

  1. That the behavior be changed to skip the creation if it finds a match for both the given release name AND that exactly one of the release(s) thus found has the same tag. When skipping it should still determine and set the upload_url and any related outputs, thus allowing any downstream steps to proceed normally.
  2. That an option be added, such as allow_duplicates, which if true would behave as it currently does otherwise it would proceed as in the above. I'd rather the default state of this new option be false, but I'd understand if the maintainers would rather it be set true to keep the default behavior unchanged.

@nogic1008
Copy link

Split "Create Release" job and "Build" job, and use upload-artifact and download-artifact to transfer URL.

  release:
    name: Create Github Release
    if: contains(github.ref, 'tags/v')
    needs: [test]
    runs-on: ubuntu-latest
    steps:
    - name: Create Release
      id: create_release
      uses: actions/create-release@v1.0.0
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      with:
        tag_name: ${{ github.ref }}
        release_name: Release ${{ github.ref }}
        draft: false
        prerelease: false
    - name: Output Release URL File
      run: echo "${{ steps.create_release.outputs.upload_url }}" > release_url.txt
    - name: Save Release URL File for publish
      uses: actions/upload-artifact@v1
      with:
        name: release_url
        path: release_url.txt
    
  publish:
    if: contains(github.ref, 'tags/v')
    needs: [test, release]
    runs-on: ubuntu-latest
    strategy:
      matrix:
        version: [foo, bar, baz]
    steps:
    - uses: actions/checkout@v1
    - name: Load Release URL File from release job
      uses: actions/download-artifact@v1
      with:
        name: release_url
    - name: Build
      run: BUILD_COMMAND --version ${{ matrix.version }} --output ./${{ matrix.version }}
        zip -r ${{ matrix.version }} ./${{ matrix.version }}
    - name: Get Release File Name & Upload URL
      id: get_release_info
      run: |
        echo ::set-output name=file_name::${REPOSITORY_NAME##*/}-${TAG_REF_NAME##*/v} # RepositoryName-v1.0.0
        value=`cat release_url/release_url.txt`
        echo ::set-output name=upload_url::$value
      env:
        TAG_REF_NAME: ${{ github.ref }}
        REPOSITORY_NAME: ${{ github.repository }}
    - name: Upload Release Asset
      id: upload-release-asset 
      uses: actions/upload-release-asset@v1.0.1
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      with:
        upload_url: ${{ steps.get_release_info.outputs.upload_url }}
        asset_path: ./${{ matrix.rid }}.zip
        asset_name: ${{ steps.get_release_info.outputs.file_name }}-${{ matrix.rid }}.zip
        asset_content_type: application/zip

@kf6kjg
Copy link

kf6kjg commented Nov 19, 2019

I prefer to have the release created only if at least one of the builds succeeded. In fact I'd prefer that it only happened if all builds succeeded. But that's my preferred workflow and there might be a way to do it using a split build process like that, but these are workarounds that add additional time and load - but at least there are workarounds. Thank you @nogic1008 for the inspiration.

@nathanielatom
Copy link

I have an alternative solution, that runs in a single (defined) job, which has worked well for me. The idea is to use an extra matrix variable on the build you want to upload the release, and use conditionals for any steps that should only get run for an upload.

Code

jobs:
  build:
    name: python ${{ matrix.python }} and ${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        python: [3.6, 3.7]
        os: [ubuntu-latest, macOS-latest, windows-latest]
        include: # define single matrix case that performs upload
          - os: ubuntu-latest
            python: 3.7
            upload: true
...
    steps:
...
      - name: build distribution tarball
        if: matrix.upload
        run: echo 42
      - name: create github release
        id: create_release
        if: matrix.upload && github.event_name == 'pull_request' && github.base_ref == 'master'
        uses: actions/create-release@master # @v1 has no body arg
...

References

@nathanielatom
Copy link

Another alternative, if you don't have a preference for which matrix build triggers upload, is to skip the matrix include thing and use step conditionals like if: strategy.job-index == 0; although I haven't tested this myself.

https://help.github.com/en/actions/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions#contexts

@extrawurst
Copy link

I recently switched to https://github.com/softprops/action-gh-release due to this problem

@kmturley
Copy link

kmturley commented Jul 5, 2020

One potential approach would be to create:

  • all.yml
  • linux.yml
  • macos.yml
  • window.yml

Then put the create release only in the all.yml

name: All platforms

on:
  push:
    tags:
      - 'v*'

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - name: Create release
      id: create_release
      uses: actions/create-release@v1
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      with:
        tag_name: ${{ github.ref }}
        release_name: Release ${{ github.ref }}

The only problem is that each platform needs the create_release upload url for it's own release:

linux.yml

    - name: Upload release
      id: upload-release-asset 
      uses: actions/upload-release-asset@v1
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      with:
        upload_url: ${{ steps.create_release.outputs.upload_url }}
        asset_path: ./build/VST3/artifact/plugin-linux.zip
        asset_name: plugin-linux.zip
        asset_content_type: application/zip

EDIT: found this blog post which is useful:
https://dev.to/eugenebabichenko/automated-multi-platform-releases-with-github-actions-1abg

@kmturley
Copy link

kmturley commented Jul 6, 2020

Another approach is mentioned in this blog post:
https://dev.to/eugenebabichenko/automated-multi-platform-releases-with-github-actions-1abg

I got it to work for building a single release containing multiple binaries:

name: Release

on:
  push:
    tags:
      - "v*"

jobs:
  create_release:
    name: Create release
    runs-on: ubuntu-latest
    outputs:
      upload_url: ${{ steps.create_release.outputs.upload_url }}
    steps:
      - name: Create release
        id: create_release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ github.ref }}
          release_name: Release ${{ github.ref }}

  build_release:
    name: Build release
    needs: create_release
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        include:
          - os: ubuntu-latest
            zip_name: plugin-linux
            generator: Unix Makefiles
          - os: macos-latest
            zip_name: plugin-mac
            generator: Xcode
          - os: windows-latest
            zip_name: plugin-win
            generator: Visual Studio 16 2019
    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Install Linux dependencies
        if: matrix.os == 'ubuntu-latest'
        run: sudo apt-get install cmake gcc "libstdc++6" libx11-xcb-dev libxcb-util-dev libxcb-cursor-dev libxcb-xkb-dev libxkbcommon-dev libxkbcommon-x11-dev libfontconfig1-dev libcairo2-dev libgtkmm-3.0-dev libsqlite3-dev libxcb-keysyms1-dev

      - name: Install macOS dependencies
        if: matrix.os == 'macOS-latest'
        run: brew install cmake

      - name: Install Windows dependencies
        if: matrix.os == 'windows-latest'
        run: |
          choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System'

      - name: Setup
        shell: bash
        run: |
          git submodule update --init --recursive
          cp -R -v ./vst2sdk/public.sdk/source/vst2.x ./vst3sdk/public.sdk/source

      - name: Build
        shell: bash
        run: |
          cmake \
            -G "${{ matrix.generator }}" \
            -DCMAKE_BUILD_TYPE=Release \
            -DSMTG_ADD_VST3_PLUGINS_SAMPLES=ON \
            -DSMTG_ADD_VST3_HOSTING_SAMPLES=OFF \
            -DSMTG_ADD_VSTGUI=ON \
            -DSMTG_MYPLUGINS_SRC_PATH=./src \
            -S ./vst3sdk \
            -B ./build
          cmake --build ./build --config Release

      - name: Compress
        shell: bash
        run: |
          cd ./build/VST3/Release
          mkdir ../artifact
          zip -r ../artifact/${{ matrix.zip_name }}.zip *

      - name: Upload
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ needs.create_release.outputs.upload_url }}
          asset_path: ./build/VST3/artifact/${{ matrix.zip_name }}.zip
          asset_name: ${{ matrix.zip_name }}.zip
          asset_content_type: application/zip

@TomasHubelbauer
Copy link

@extrawurst can you show how that Action solves this problem? I wasn't able to figure it out based on their readme. They don't seem to provide an example of use with a build matrix. I am hoping it might be possible to run three OS builds and then create a release only if all three went through and only after they all did. Is this possible with that Action?

@extrawurst
Copy link

@TomasHubelbauer no that problem still persists if one of your builds fails the resulting artefact simply is missing

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants