Skip to content

Commit

Permalink
Deployment github workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
devo1929 committed Nov 28, 2021
1 parent 03129f1 commit 83b412f
Show file tree
Hide file tree
Showing 12 changed files with 325 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
name: build installer

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
# push:
# branches: [ master ]
# pull_request:
# branches: [ master ]
workflow_dispatch:

jobs:
build-installer:
Expand Down
170 changes: 170 additions & 0 deletions .github/workflows/deployment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
name: update-deploy

on:
# Run on push to master
push:
branches:
- master

# Run this manually
workflow_dispatch:

workflow_run:
# Run this after the release workflow has completed
workflows: [ release ]
types:
- completed
jobs:
# This job uses a Docker Ubuntu container to download necessary files/tools from the server to create the update.
# An Ubuntu Docker container is necessary, because we have more control over what Ubuntu programs are available to us,
# because we can install them into a Github workflow container.
download-tools:
# This job requires an Ubuntu platform so that it can create the Ubuntu Docker container.
runs-on: ubuntu-latest
environment: cncnet

steps:
# Checkout the repo
- name: Checkout repo
uses: actions/checkout@v2
with:
fetch-depth: 0 # required for gitversion

# Run Gitversion - https://gitversion.net/docs/
# This runs gitversion in a docker container and writes the output json to a local file.
# This output file will be available in the uploaded artifact later in the workflow.
- name: Run Gitversion Docker
run: docker run --rm -v "$(pwd):/repo" gittools/gitversion:latest-debian.10 /repo >gitversion.json

# Get access to the properties from the gitversion output file
- name: Get gitversion.json properties
id: gitversion
uses: zoexx/github-action-json-file-properties@release
with:
file_path: "gitversion.json"

# Update versionconfig.ini with gitversion version info
- name: Update versionconfig.ini
# replace the second line in the file with the proper version number (X.Y.Z-dev.N)
run: sed -i "2 s/.*/${{steps.gitversion.outputs.SemVer}}/" versionconfig.ini

# We need to download necessary "tools" for the update (including VersionWriter.exe). Github Workflow linux containers do
# not the necessary programs installed by default and we do not have the ability to install it.
# So, we use our own Docker container to do so.

# Build the container from our Dockerfile
- name: Build docker container
run: docker build -t download-tools ${{ github.workspace }}/updater-scripts/download-tools

# Run the newly built container
- name: Run docker container
env:
# These are secret variables that should be stored in Github for the repository.
SSH_KEY: ${{ secrets.SSH_KEY }}
SSH_HOST: ${{ secrets.SSH_HOST }}
SSH_PASS: ${{ secrets.SSH_PASS }}
SSH_USER: ${{ secrets.SSH_USER }}
SSH_PATH_TOOLS: ${{ secrets.SSH_PATH_TOOLS }}
SSH_PORT: ${{ secrets.SSH_PORT }}
run: docker run -v ${{ github.workspace }}:/download-tools -e SSH_KEY -e SSH_HOST -e SSH_PASS -e SSH_USER -e SSH_PATH_TOOLS -e SSH_PORT -i download-tools

# Archive this repo, excluding unnecessary files for the update
- name: Zip dependencies
run: zip -r archive.zip . -x *.git\* *.github\* *InnoSetup\* *.gitignore *.gitattributes

# Upload the archive artifact for the next job
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: artifact
path: archive.zip

# We have the necessary tools and the proper version has been written to our versionconfig.ini file.
# Now, we need to actually run VersionWriter.exe.

version-writer:
# This jub runs runs on a Windows platform, because we need to run the VersionWriter executable.
runs-on: windows-latest
environment: cncnet
# Make sure we wait for the "download-tools" job to complete successfully
needs: download-tools

steps:
# Download the previous artifact archive
- name: Get artifact
uses: actions/download-artifact@v2
with:
name: artifact

# Extract the archive
- name: Extract archive
run: 7z x archive.zip

# Run the VersionWriter
- name: Run VersionWriter.exe
run: ./VersionWriter.exe /S

# Remove files we do not want in the new archive
- name: Clean up files
run: rm archive.zip && rm VersionWriter.exe && rm -r VersionWriter-CopiedFiles

# Create new archive
- name: Create new versioned archive
run: 7z a -r archive.zip .

# Upload the versioned archive artifact for next job
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: artifact
path: archive.zip

# We now have a zip file containing the exact files necessary for the next update. We need to
# upload these files to the server in the proper version folder.

# This job creates the appropriate version folder on the server and uploads our updated files to it.
upload-version:
runs-on: ubuntu-latest
environment: cncnet
needs: version-writer

steps:
# Download the previous artifact archive
- name: Get artifact
uses: actions/download-artifact@v2
with:
name: artifact

# Extract the archive
- name: Extract archive
run: 7z x archive.zip

# Get access to the properties from the gitversion output file
- name: Get gitversion.json properties
id: gitversion
uses: zoexx/github-action-json-file-properties@release
with:
file_path: "gitversion.json"

# Create deploy archive
- name: Create deploy archive
run: tar --exclude=*updater-scripts\* --exclude=archive.zip -czvf archive.tar.gz *

# Build the container from our Dockerfile
- name: Build docker container
run: docker build -t upload-version ${{ github.workspace }}/updater-scripts/upload-version

# Run the newly built container
- name: Run docker container
env:
# These are secret variables that should be stored in Github for the repository.
SSH_KEY: ${{ secrets.SSH_KEY }}
SSH_HOST: ${{ secrets.SSH_HOST }}
SSH_PASS: ${{ secrets.SSH_PASS }}
SSH_USER: ${{ secrets.SSH_USER }}
SSH_PATH_UPDATES: ${{ secrets.SSH_PATH_UPDATES }}
SSH_PORT: ${{ secrets.SSH_PORT }}
VERSION: ${{ steps.gitversion.outputs.MajorMinorPatch }}${{ steps.gitversion.outputs.PreReleaseLabelWithDash }}
run: docker run -v ${{ github.workspace }}:/upload-version -e SSH_KEY -e SSH_HOST -e SSH_PASS -e SSH_USER -e SSH_PATH_UPDATES -e SSH_PORT -e VERSION -i upload-version


14 changes: 14 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: release

on:
release:
types: [ published ]

jobs:
noop:
# restrict this to only run for tags that start with 'yr-'
if: startsWith(${{ github.ref }}, 'refs/tags/yr-')
runs-on: ubuntu-latest
steps:
- name: noop
run: echo Release created for tag ${{ github.ref }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,4 @@ ra2md.mix
stats.dmp
wdt.mix
/InnoSetup/output
/gitversion.json
40 changes: 40 additions & 0 deletions DEPLOYMENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# CnCNet Yuri's Revenge Client Package Deployments

This describes the workflow for release/deployments.

## Versioning

Deployments are currently set up for [Continuous Deployment](https://gitversion.net/docs/reference/modes/continuous-deployment). Versioning is auto incremented. There are two triggers for deployments and versioning:

1. Publishing a release: When a release is created, the corresponding tag name should be created in the format **yr-X.Y** or **yr-X.Y.Z**, where **X** is major, **Y** is minor, and **Z** is an optional patch. When a tag is created in this format, a deployment will occur for that exact version. Examples:
1. If the tag **yr-8.7** is created, the next deployed version in this case will be **8.7.0**.
2. If the tag **yr-8.7.1** is created, the next deployed version in this case will be **8.7.1**.

2. Merging into master: When this happens, an auto incremented dev version of the client will be created and deployed. This auto incremented version will be the last **tag** version +1 patch. Examples:

1. If the latest tag is **yr-8.6**, the next deployed version will be **8.6.1-dev**.
2. If the latest tag is **yr-8.6.1**, the next deployed version will be **8.6.2-dev**.

## Workflow

This seciton describes the proper workflow for publishing new versions of the client. Below is an example of a "current state" scenario.

Current state: The client is on version **8.6** and a git tag of **yr-8.6** exists.

1. A PR of new code is created and merged OR code is pushed directly to master.
2. The **deployment** Github Action is triggered and deploys the version **8.6.1-dev** to the server. The **version** file generated by VersionWriter.exe will have the version of **8.6.1-dev.1**.
3. **yrdev** on the server is linked to **8.6.1-dev** deployment (**manual process**). This version is now live for dev testers.
4. Another PR of new code is created and merged OR code is pushed directly to master.
5. The **deployment** Github Action is triggered and deploys an updated version of **8.6.1-dev** to the server. The **version** file generated by VersionWriter.exe will have the version of **8.6.1-dev.2**. This should trigger an update notification for anyone testing dev versions.
6. The version **8.6.1-dev** has been determined to be stable and is tagged in Github as **yr-8.7** (**manual process**).
7. The **release** Github Action is triggered. This then triggers the **deployment** Github Action which deploys the version **8.7.0** to the server.
8. **yrdev** on the server is linked to **8.7.0** (**manual process**)
* This is optionally done for "smoke testing" purposes. However, if the tag was created from the latest commit in the **master** branch, which should have been the latest version deployed to **8.6.1-dev**, the versions **8.6.1-dev** and **8.7.0** are essentially the same.
9. **yr** on the server is linked to **8.7.0**. This version is now live for all.

## Security and Approvals

For security reasons, the **master** branch has protection rules in place to prevent unauthorized pushes/merges to master and thus unauthorized deployments.
1. Pushes directly to master are disabled for non admins. Changes to master must be made through a PR.
2. PRs for non admins require a minimum of 1 approval.
3. Approvals on PRs that are "updated" by new commits are immediately dismissed. These PRs must be re-approved.
3 changes: 3 additions & 0 deletions GitVersion.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
tag-prefix: 'yr-'
continuous-delivery-fallback-tag: dev
mode: ContinuousDeployment
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
# CnCNet Yuri's Revenge Client Package

The official CnCNet [Yuri's Revenge](https://cncnet.org/yuris-revenge) package for online.
The official CnCNet [Yuri's Revenge](https://cncnet.org/yuris-revenge) package for online.
This package is an add-on to the [XNA CnCNet Client](https://github.com/CnCNet/xna-cncnet-client) by [Rampastring](https://github.com/Rampastring)

### Contributing


### Contributing
* [dkeetonx](https://github.com/dkeetonx)
* [GrantBartlett](https://github.com/GrantBartlett)
* [Martin](https://forums.cncnet.org/profile/32538-ravage/)
* [Kerbiter](https://github.com/Metadorius)
* [Burg](https://github.com/alexp8)
* [Burg](https://github.com/alexp8)
* [devo1929](htttps://github.com/devo1929)

### Deployments

[Documentation](DEPLOYMENTS.md)
13 changes: 13 additions & 0 deletions updater-scripts/download-tools.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/sh
SSH_KEY_FILE=$1
SSH_USER=$2
SSH_PASS=$3
SSH_HOST=$4
SSH_PATH_TOOLS=$5
SSH_PORT=$6

chmod 400 $SSH_KEY_FILE

echo downloading tools
sshpass -p $SSH_PASS -P passphrase scp -o StrictHostKeyChecking=no -i $SSH_KEY_FILE -P $SSH_PORT $SSH_USER@$SSH_HOST:$SSH_PATH_TOOLS/gamemd-spawn.exe ./tools
sshpass -p $SSH_PASS -P passphrase scp -o StrictHostKeyChecking=no -i $SSH_KEY_FILE -P $SSH_PORT $SSH_USER@$SSH_HOST:$SSH_PATH_TOOLS/VersionWriter.exe ./tools
8 changes: 8 additions & 0 deletions updater-scripts/download-tools/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM ubuntu:latest

RUN apt-get update && apt-get install -y sshpass

COPY entrypoint.sh /
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

22 changes: 22 additions & 0 deletions updater-scripts/download-tools/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash
#uncomment this ONLY when running locally, for debugging output purposes
#set -x

# create our key file to pass to scp
cd download-tools
echo -e ${SSH_KEY}>__tmp_key_file
chmod 400 __tmp_key_file

# download necessary tools for update
echo uploading version
sshpass -p ${SSH_PASS} -P passphrase scp -o StrictHostKeyChecking=no -i __tmp_key_file -P ${SSH_PORT} ${SSH_USER}@${SSH_HOST}:${SSH_PATH_TOOLS}/gamemd-spawn.exe .
sshpass -p ${SSH_PASS} -P passphrase scp -o StrictHostKeyChecking=no -i __tmp_key_file -P ${SSH_PORT} ${SSH_USER}@${SSH_HOST}:${SSH_PATH_TOOLS}/VersionWriter.exe .

# clean up temporary key file
rm __tmp_key_file

# uncomment this to debug the directory contents during github action
dir

# uncomment this when running locally to keep the container alive for debugging purposes
#tail -f /dev/null
8 changes: 8 additions & 0 deletions updater-scripts/upload-version/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM ubuntu:latest

RUN apt-get update && apt-get install -y sshpass

COPY entrypoint.sh /
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

33 changes: 33 additions & 0 deletions updater-scripts/upload-version/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/bin/bash
#uncomment this ONLY when running locally, for debugging output purposes
#set -x

# create our key file to pass to scp
cd upload-version
echo -e ${SSH_KEY}>__tmp_key_file
chmod 400 __tmp_key_file

# create necessary version folder for update
echo creating version folder
sshpass -p ${SSH_PASS} -P passphrase ssh -o StrictHostKeyChecking=no -i __tmp_key_file -p ${SSH_PORT} ${SSH_USER}@${SSH_HOST} mkdir ${SSH_PATH_UPDATES}/${VERSION}

# upload deploy archive
sshpass -p ${SSH_PASS} -P passphrase scp -o StrictHostKeyChecking=no -i __tmp_key_file -P ${SSH_PORT} archive.tar.gz ${SSH_USER}@${SSH_HOST}:${SSH_PATH_UPDATES}/${VERSION}/

# extract the deploy archive
sshpass -p ${SSH_PASS} -P passphrase ssh -o StrictHostKeyChecking=no -i __tmp_key_file -p ${SSH_PORT} ${SSH_USER}@${SSH_HOST} tar -xzvf ${SSH_PATH_UPDATES}/${VERSION}/archive.tar.gz -C ${SSH_PATH_UPDATES}/${VERSION}

# delete the deploy archive from server
sshpass -p ${SSH_PASS} -P passphrase ssh -o StrictHostKeyChecking=no -i __tmp_key_file -p ${SSH_PORT} ${SSH_USER}@${SSH_HOST} rm ${SSH_PATH_UPDATES}/${VERSION}/archive.tar.gz

# update permissions on all update files for update download purposes
sshpass -p ${SSH_PASS} -P passphrase ssh -o StrictHostKeyChecking=no -i __tmp_key_file -p ${SSH_PORT} ${SSH_USER}@${SSH_HOST} chmod 777 --recursive ${SSH_PATH_UPDATES}/${VERSION}/*

# clean up temporary key file
rm __tmp_key_file

# uncomment this to debug the directory contents during github action
dir

# uncomment this when running locally to keep the container alive for debugging purposes
#tail -f /dev/null

0 comments on commit 83b412f

Please sign in to comment.