Open nukeop opened 4 years ago
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:
upload_url
and any related outputs, thus allowing any downstream steps to proceed normally.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.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
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.
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.
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
...
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.
I recently switched to https://github.com/softprops/action-gh-release due to this problem
One potential approach would be to create:
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
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
@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?
@TomasHubelbauer no that problem still persists if one of your builds fails the resulting artefact simply is missing
I have a matrix which results in 3 builds. Is there a way to ensure only the first one will draft a new release?