Add multi-os Github release workflow (#159)

This commit is contained in:
sergystepanov 2020-04-08 23:01:02 +03:00 committed by GitHub
parent 8484eca293
commit e2fc8696c8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 300 additions and 27 deletions

207
.github/workflows/release.yml vendored Normal file
View file

@ -0,0 +1,207 @@
# ------------------------------------------------------------------------
# Release workflow for multiple OSes (Linux x64, macOS x64, Windows x64)
# ------------------------------------------------------------------------
# +---------------+ +---------------+
# | BUILD | +---------------+ | PUBLISH |
# +---------------+ | RELEASE | +---------------+
# | compile | +---------------+ | upload build |
# | | | | | | | |
# | nix ---> | -> | get release | -> | <-- nix |
# | mac ------> | | (use old) | | <--- mac |
# | win ----> | | | <- | <---- win |
# +---------------+ +---------------+ +---------------+
# ------------------------------------------------------------------------
# Usage:
# This workflow adds multi-os application builds when v-prefixed tags
# pushed into the repository, e.g. git tag v9001 & git push --tags or
# a new Github release is created with such tags.
# ------------------------------------------------------------------------
name: Release
# run only when pushing v-prefixed SemVer tags (e.g. v1.0.0, v2.0.1, and etc.)
on:
push:
tags:
- 'v*'
env:
go-version: 1.13
app-name: cloud-game
app-arch: x86_64
jobs:
# run app build for each OS in parallel
build:
name: Build
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
env:
release-dir: _release
steps:
- name: Get the source
uses: actions/checkout@v2
- name: Set up Go
uses: actions/setup-go@v1
with:
go-version: ${{ env.go-version }}
- name: Set up Go environment
shell: bash
# add Go's bin folder into environmet (to be able to call its tools)
run: |
echo "::set-env name=GOPATH::$(go env GOPATH)"
echo "::add-path::$(go env GOPATH)/bin"
- name: Get Linux dev libraries and tools
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y make pkg-config libvpx-dev libopus-dev libopusfile-dev
- name: Get MacOS dev libraries and tools
if: matrix.os == 'macos-latest'
run: |
brew install libvpx pkg-config opus opusfile
- name: Get Windows dev libraries and tools
if: matrix.os == 'windows-latest'
uses: numworks/setup-msys2@v1
with:
msystem: MINGW64
path-type: inherit
- name: Load Go modules maybe?
uses: actions/cache@v1
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Build Windows app
if: matrix.os == 'windows-latest'
run: |
msys2do pacman -S --noconfirm --needed make mingw-w64-x86_64-gcc mingw-w64-x86_64-pkg-config mingw-w64-x86_64-dlfcn mingw-w64-x86_64-libvpx mingw-w64-x86_64-opusfile
msys2do make release RELEASE_DIR=${{ env.release-dir }} DLIB_SEARCH_PATTERN=/mingw.*dll CORE_EXT=dll
- name: Build Linux app
if: matrix.os == 'ubuntu-latest'
run: |
make release RELEASE_DIR=${{ env.release-dir }} DLIB_SEARCH_PATTERN=/usr/lib.*\\\\s CORE_EXT=so
- name: Build macOS app
if: matrix.os == 'macos-latest'
run: |
# skip copy libs due to outrageous otool behaviour, depend on sys install
# should be recursive + paths rewritten to @executable_path
# lddx seems to be working ok
go get github.com/jtanx/lddx
make release RELEASE_DIR=${{ env.release-dir }} DLIB_ALTER=true DLIB_TOOL="lddx -r -c" CORE_EXT=dylib
- name: Save built app for upload
uses: actions/upload-artifact@v1
with:
name: ${{ runner.os }}
path: ${{ env.release-dir }}
release:
name: Create or find Github release
needs: build
runs-on: ubuntu-latest
steps:
- name: Trying to find existing release
uses: actions/github-script@0.9.0
id: release_search
with:
github-token: ${{secrets.GITHUB_TOKEN}}
result-encoding: string
script: |
try {
const release = await github.repos.getReleaseByTag({
owner: context.repo.owner,
repo: context.repo.repo,
tag: context.ref.replace('refs/tags/', '')
});
return release.data.upload_url;
} catch (ignored) {}
return '';
- name: Create new release maybe?
id: create_release
if: steps.release_search.outputs.result == ''
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: ${{ github.ref }}
draft: false
prerelease: false
# pass assets upload url of existing or new release
# between jobs (VMs) through txt files
- name: Get release upload URL
run: |
echo '${{ steps.create_release.outputs.upload_url }}${{ steps.release_search.outputs.result }}' > upload_url
- name: Save release upload URL
uses: actions/upload-artifact@v1
with:
name: upload_url
path: ./
publish:
name: Publish
needs: release
strategy:
matrix:
# should be same as runner.os
target-os: [Linux, macOS, Windows]
include:
- target-os: Linux
compress: tar -zcf
archive-ext: tar.gz
archive-mime: tar
- target-os: macOS
compress: tar -zcf
archive-ext: tar.gz
archive-mime: tar
- target-os: Windows
compress: zip -qq -r
archive-ext: zip
archive-mime: zip
runs-on: ubuntu-latest
steps:
- name: Get version tag
id: get_version
run: |
echo ::set-output name=version::${GITHUB_REF#refs/tags/}
- name: Get release upload url
uses: actions/download-artifact@v1
with:
name: upload_url
- name: Read release upload url
id: upload_url
run: |
value=`cat upload_url/upload_url`
echo "::set-output name=url::$value"
- name: Get the build
uses: actions/download-artifact@v1
with:
name: ${{ matrix.target-os }}
- name: Compress the build
id: compress
# compress all the files without a parent dir
# (cd into arch dir -> make archive in its parent -> go back)
run: |
cd ./${{ matrix.target-os }}
archive='${{ env.app-name }}-${{ steps.get_version.outputs.version }}-${{ matrix.target-os }}-${{ env.app-arch }}'
compress='${{ matrix.compress }} ../${archive,,}.${{ matrix.archive-ext }} *'
eval $compress
cd ../
echo ::set-output name=archive_name::${archive,,}.${{ matrix.archive-ext }}
- name: Upload release asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.upload_url.outputs.url }}
asset_path: ./${{ steps.compress.outputs.archive_name }}
asset_name: ${{ steps.compress.outputs.archive_name }}
asset_content_type: application/${{ matrix.archive-mime }}

1
.gitignore vendored
View file

@ -60,5 +60,6 @@ bin/
.coverage.out
_output/
./build
release/
.dockerignore

70
Makefile vendored
View file

@ -58,14 +58,16 @@ cover:
clean:
@rm -rf bin
@rm -rf build
@go clean
@go clean ./cmd/*
build:
go build -a -tags netgo -ldflags '-w' -o bin/coordinator ./cmd/coordinator
go build -a -tags netgo -ldflags '-w' -o bin/worker ./cmd/worker
dev.tools:
./hack/scripts/install_tools.sh
dev.build: compile
go build -a -tags netgo -ldflags '-w' -o bin/coordinator ./cmd/coordinator
go build -a -tags netgo -ldflags '-w' -o bin/worker ./cmd/worker
dev.build: compile build
dev.build-local:
go build -o bin/coordinator ./cmd/coordinator
@ -81,3 +83,63 @@ dev.run-docker:
docker rm cloud-game-local || true
# Coordinator and worker should be run separately.
docker run --privileged -v $PWD/games:/cloud-game/games -d --name cloud-game-local -p 8000:8000 -p 9000:9000 cloud-game-local bash -c "coordinator --v=5 & worker --coordinatorhost localhost:8000"
# RELEASE
# Builds the app for new release.
#
# Folder structure:
# release
# - coordinator/
# - web/
# - coordinator
# - worker/
# - assets/
# - emulator/libretro/cores/ (filtered by extension)
# - games/
# - worker
#
# params:
# - RELEASE_DIR: the name of the output folder (default: _release).
# - DLIB_TOOL: the name of a dynamic lib copy tool (with params) (e.g., ldd -x -y; defalut: ldd).
# - DLIB_SEARCH_PATTERN: a grep filter of the output of the DLIB_TOOL (e.g., mylib.so; default: .*so).
# Be aware that this search pattern will return only matched regular expression part and not the whole line.
# de. -> abc def ghj -> def
# Makefile special symbols should be escaped with \.
# - DLIB_ALTER: a special flag to use altered dynamic copy lib tool for macOS only.
# - CORE_EXT: a file extension of the cores to copy into the release.
#
# example:
# make release DLIB_TOOL="ldd -x" DLIB_SEARCH_PATTERN=/usr/lib.*\\\\s LIB_EXT=so
#
RELEASE_DIR ?= release
DLIB_TOOL ?= ldd
DLIB_SEARCH_PATTERN ?= .*so
DLIB_ALTER ?= false
CORE_EXT ?= *
COORDINATOR_DIR = ./$(RELEASE_DIR)/coordinator
WORKER_DIR = ./$(RELEASE_DIR)/worker
CORES_DIR = assets/emulator/libretro/cores
GAMES_DIR = assets/games
.PHONY: release
.SILENT: release
release: clean build
rm -rf ./$(RELEASE_DIR) && mkdir ./$(RELEASE_DIR)
mkdir $(COORDINATOR_DIR) && mkdir $(WORKER_DIR)
cp ./bin/coordinator $(COORDINATOR_DIR) && cp ./bin/worker $(WORKER_DIR)
chmod +x $(COORDINATOR_DIR)/coordinator $(WORKER_DIR)/worker
ifeq ($(DLIB_ALTER),false)
for bin in $$($(DLIB_TOOL) $(WORKER_DIR)/worker | grep -o $(DLIB_SEARCH_PATTERN)); \
do cp -v "$$bin" $(WORKER_DIR); \
done
else
$(DLIB_TOOL) $(WORKER_DIR) $(WORKER_DIR)/worker
endif
cp -R ./web $(COORDINATOR_DIR)
mkdir -p $(WORKER_DIR)/$(GAMES_DIR)
ifneq (,$(wildcard ./$(GAMES_DIR)))
cp -R ./$(GAMES_DIR) $(WORKER_DIR)/assets
endif
mkdir -p $(WORKER_DIR)/$(CORES_DIR)
ifneq (,$(wildcard ./$(CORES_DIR)/*.$(CORE_EXT)))
cp -R ./$(CORES_DIR)/*.$(CORE_EXT) $(WORKER_DIR)/$(CORES_DIR)
endif

49
README.md vendored
View file

@ -1,19 +1,22 @@
# CloudRetro
**Open-source Cloud Gaming Service For Retro Games**
**Video demo**: https://www.youtube.com/watch?v=GUBrJGAxZZg
<img src="https://github.com/giongto35/cloud-game/workflows/Release/badge.svg" alt="Release status">
**Open-source Cloud Gaming Service For Retro Games**
**Video demo**: https://www.youtube.com/watch?v=GUBrJGAxZZg
**My Slide at GopherconVN2019**: https://docs.google.com/presentation/d/1VFv8l2hVUINv2U36r7L11g4Oa_zVjHlr6MYymUbQXT4/edit?usp=sharing
## Introduction
CloudRetro provides an open-source cloud gaming platform for retro games. It started as an experiment for testing cloud gaming performance with [WebRTC](https://github.com/pion/webrtc/) and [libretro](https://www.libretro.com/), and now it aims to deliver the most modern and convenient gaming experience through the technology.
CloudRetro provides an open-source cloud gaming platform for retro games. It started as an experiment for testing cloud gaming performance with [WebRTC](https://github.com/pion/webrtc/) and [libretro](https://www.libretro.com/), and now it aims to deliver the most modern and convenient gaming experience through the technology.
Theoretically, in cloud gaming, games are run on remote servers and media are streamed to the player optimally to ensure the most comfortable user interaction. It opens the ability to play any retro games on web-browser directly, which are fully compatible with multi-platform like Desktop, Android, ~~IOS~~. It enhances crowdplay ([TwitchPlaysPokemon](https://en.wikipedia.org/wiki/Twitch_Plays_Pok%C3%A9mon)) with realtime interaction. E.g: [Play Pokemon Emerald together](http://cloudretro.io/?id=652e45d78d2b91cd%7CPokemon%20-%20Emerald%20Version%20%28U%29).
Theoretically, in cloud gaming, games are run on remote servers and media are streamed to the player optimally to ensure the most comfortable user interaction. It opens the ability to play any retro games on web-browser directly, which are fully compatible with multi-platform like Desktop, Android, ~~IOS~~. It enhances crowdplay ([TwitchPlaysPokemon](https://en.wikipedia.org/wiki/Twitch_Plays_Pok%C3%A9mon)) with realtime interaction. E.g: [Play Pokemon Emerald together](http://cloudretro.io/?id=652e45d78d2b91cd%7CPokemon%20-%20Emerald%20Version%20%28U%29).
## Try the service at
Single play: **[http://cloudretro.io](http://cloudretro.io)**
Crowd play: **[Pokemon Emerald](http://cloudretro.io/?id=652e45d78d2b91cd%7CPokemon%20-%20Emerald%20Version%20%28U%29)**
*Chrome and Chrome on Android is recommended. It's not working on iPhone and some other explorers. Click help button in the game UI to see keyboard mapping.*
Single play: **[http://cloudretro.io](http://cloudretro.io)**
Crowd play: **[Pokemon Emerald](http://cloudretro.io/?id=652e45d78d2b91cd%7CPokemon%20-%20Emerald%20Version%20%28U%29)**
*Chrome and Chrome on Android is recommended. It's not working on iPhone and some other explorers. Click help button in the game UI to see keyboard mapping.*
\*In ideal network condition and less resource contention on servers, the game will run smoothly as in the video demo. Because I only hosted the platform on limited servers in US East, US West, Eu, Singapore, you may experience some latency issues + connection problem. You can try hosting the service following the instruction the next section to have a better sense of performance.
\*In ideal network condition and less resource contention on servers, the game will run smoothly as in the video demo. Because I only hosted the platform on limited servers in US East, US West, Eu, Singapore, you may experience some latency issues + connection problem. You can try hosting the service following the instruction the next section to have a better sense of performance.
| Screenshot | Screenshot |
| :--------------------------------------------: | :--------------------------------------------: |
@ -31,7 +34,7 @@ Crowd play: **[Pokemon Emerald](http://cloudretro.io/?id=652e45d78d2b91cd%7CPoke
## Run on local by Docker
You try running the server directly by `make dev.run-docker`. It will spawn a docker environment and you can access the service on `localhost:8000`.
You try running the server directly by `make dev.run-docker`. It will spawn a docker environment and you can access the service on `localhost:8000`.
## Development environment
@ -77,18 +80,18 @@ Because the coordinator and workers need to run simultaneously. Workers connect
- [Wiki](https://github.com/giongto35/cloud-game/wiki)
## FAQ
- [FAQ](https://github.com/giongto35/cloud-game/wiki/FAQ)
- [FAQ](https://github.com/giongto35/cloud-game/wiki/FAQ)
## Crowd Play, play game together
By clicking these deep link, you can join the game directly and play it together with other people.
- [Play Pokemon Emerald](http://cloudretro.io/?id=652e45d78d2b91cd%7CPokemon%20-%20Emerald%20Version%20%28U%29)
By clicking these deep link, you can join the game directly and play it together with other people.
- [Play Pokemon Emerald](http://cloudretro.io/?id=652e45d78d2b91cd%7CPokemon%20-%20Emerald%20Version%20%28U%29)
- [Fire Emblem](http://cloudretro.io/?id=314ea4d7f9c94d25___Fire%20Emblem%20%28U%29%20%5B%21%5D)
- [Advance War](http://cloudretro.io/?id=10fe582a7635b039___Advance%20Wars%20%28USA%29)
- [Harvest Moon](http://cloudretro.io/?id=3f7462269e976303___Harvest%20Moon%20-%20Back%20to%20Nature%20%28USA%29)
- [Play Pokemon Fire Red](http://cloudretro.io/?id=68bf168be6728020___Pokemon%20-%20Fire%20Red%20Version%20%28U%29%20%28V1.1%29)
- [Mario](http://cloudretro.io/?id=1953c570fee1f9e4___Super%20Mario%20Bros)
- [Play Pokemon Fire Red](http://cloudretro.io/?id=68bf168be6728020___Pokemon%20-%20Fire%20Red%20Version%20%28U%29%20%28V1.1%29)
- [Mario](http://cloudretro.io/?id=1953c570fee1f9e4___Super%20Mario%20Bros)
And you can host the new game by yourself by accessing [cloudretro.io](http://cloudretro.io) and click "share" button to generate a deeplink to your current game.
And you can host the new game by yourself by accessing [cloudretro.io](http://cloudretro.io) and click "share" button to generate a deeplink to your current game.
_Disclaimer: You may experience lagging when joining a room because the room is in a different zone. In that case, you should create a new room for crowd play._
![screenshot](docs/img/crowdplay.gif)
@ -100,17 +103,17 @@ _Disclaimer: You may experience lagging when joining a room because the room is
## Credits
* *Pion* Webrtc team for the incredible Golang Webrtc library and their supports https://github.com/pion/webrtc/.
* *libretro/kivutar* Golang libretro https://github.com/libretro/go-nanoarch and https://www.libretro.com/.
* *Pion* Webrtc team for the incredible Golang Webrtc library and their supports https://github.com/pion/webrtc/.
* *libretro/kivutar* Golang libretro https://github.com/libretro/go-nanoarch and https://www.libretro.com/.
* *gen2brain* for the h264 go encoder https://github.com/gen2brain/x264-go
* *poi5305* for the video encoding https://github.com/poi5305/go-yuv2webRTC.
* *fogleman* for the NES emulator https://github.com/fogleman/nes.
* *poi5305* for the video encoding https://github.com/poi5305/go-yuv2webRTC.
* *fogleman* for the NES emulator https://github.com/fogleman/nes.
## Author
Nguyen Huu Thanh
https://www.linkedin.com/in/huuthanhnguyen/
Nguyen Huu Thanh
https://www.linkedin.com/in/huuthanhnguyen/
Tri Dang Minh
https://trich.im
Tri Dang Minh
https://trich.im