From 6c7f985864e68007353d5e38ad84daf4d3941a9f Mon Sep 17 00:00:00 2001 From: EvilFactory Date: Thu, 29 Aug 2024 18:45:48 -0300 Subject: [PATCH] CI setup --- .github/dependabot.yml | 9 +++ .github/workflows/build.yml | 47 ++++++++++++ .github/workflows/create-prerelease.yml | 89 ++++++++++++++++++++++ .github/workflows/harden-ci-security.yml | 21 +++++ .github/workflows/on-push-master.yml | 22 ++++++ .github/workflows/on-push-pr.yml | 17 +++++ .github/workflows/on-update-dot-github.yml | 14 ++++ .github/workflows/publish-release.yml | 68 +++++++++++++++++ .github/workflows/run-tests.yml | 43 +++++++++++ Deploy/DeployAll.sh | 5 ++ 10 files changed, 335 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/create-prerelease.yml create mode 100644 .github/workflows/harden-ci-security.yml create mode 100644 .github/workflows/on-push-master.yml create mode 100644 .github/workflows/on-push-pr.yml create mode 100644 .github/workflows/on-update-dot-github.yml create mode 100644 .github/workflows/publish-release.yml create mode 100644 .github/workflows/run-tests.yml create mode 100644 Deploy/DeployAll.sh diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..5236a35 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://json.schemastore.org/dependabot-2.0.json + +version: 2 +updates: + - package-ecosystem: github-actions + target-branch: develop + directory: / + schedule: + interval: daily diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..05eb976 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,47 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json + +name: Build + +on: + workflow_dispatch: + workflow_call: + inputs: + target: + required: true + type: string + +env: + CI_DIR: 717a3c49-f5dc-42eb-b332-fcf2988d00e3 + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout branch + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + with: + ref: ${{ inputs.target }} + submodules: recursive + + - name: Setup .NET + uses: actions/setup-dotnet@6bd8b7f7774af54e05809fcc5431931b3eb1ddee # v4.0.1 + with: + dotnet-version: | + 6.0.x + + - name: Run deploy script + run: | + cd Deploy + chmod +x DeployAll.sh + ./DeployAll.sh + + - name: Create tarball + run: | + mkdir -p "$CI_DIR" + tar -czf "$CI_DIR/build.tar.gz" -C Deploy/bin . + + - name: Upload tarball + uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 + with: + name: build + path: ${{ env.CI_DIR }}/build.tar.gz diff --git a/.github/workflows/create-prerelease.yml b/.github/workflows/create-prerelease.yml new file mode 100644 index 0000000..8ec7c33 --- /dev/null +++ b/.github/workflows/create-prerelease.yml @@ -0,0 +1,89 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json + +name: Create pre-release + +on: + schedule: + - cron: "0 0 * * *" + workflow_dispatch: + +jobs: + check-if-release-needed: + runs-on: ubuntu-latest + outputs: + latest-commit-sha: ${{ steps.get-latest-commit.outputs.result }} + has-new-commits: ${{ steps.check-for-new-commits.outputs.has-new-commits }} + steps: + - name: Extract branch name + id: extract-branch-name + run: | + echo "result=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> "$GITHUB_OUTPUT" + - name: Sanity checks + if: ${{ github.event_name == 'workflow_dispatch' && steps.extract-branch-name.outputs.result != 'develop' }} + run: | + echo "::error::this workflow can only be run on the \"develop\" branch" + exit 1 + + - name: Get latest nightly-tagged commit + id: get-latest-tag + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + with: + result-encoding: string + script: | + try { + const ref = await github.rest.git.getRef({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: "tags/nightly", + }); + return ref.data.object.sha; + } catch (err) { + if (err.name === "HttpError" && err.status === 404) { + return "tag-doesnt-exist"; + } + throw err; + } + + - name: Get latest commit on dev branch + id: get-latest-commit + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + with: + result-encoding: string + script: | + const ref = await github.rest.git.getRef({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: "heads/develop", + }); + return ref.data.object.sha; + + - name: Check for new commits + id: check-for-new-commits + if: ${{ steps.get-latest-tag.outputs.result != 'tag-doesnt-exist' }} + env: + LATEST_TAGGED_SHA: "${{ steps.get-latest-tag.outputs.result }}" + LATEST_SHA: "${{ steps.get-latest-commit.outputs.result }}" + run: | + if [[ -z "$LATEST_TAGGED_SHA" ]]; then + echo "::error::LATEST_TAGGED_SHA env var is invalid" + exit 1 + fi + if [[ -z "$LATEST_SHA" ]]; then + echo "::error::LATEST_TAGGED_SHA env var is invalid" + exit 1 + fi + + if [[ "$LATEST_TAGGED_SHA" == "$LATEST_SHA" ]]; then + echo "has-new-commits=false" >> "$GITHUB_OUTPUT" + else + echo "has-new-commits=true" >> "$GITHUB_OUTPUT" + fi + + publish-release: + #needs: [check-if-release-needed] + #if: ${{ needs.check-if-release-needed.outputs.has-new-commits == 'true' }} + uses: ./.github/workflows/publish-release.yml + with: + target: ${{ needs.check-if-release-needed.outputs.latest-commit-sha }} + tag: nightly + prerelease: true diff --git a/.github/workflows/harden-ci-security.yml b/.github/workflows/harden-ci-security.yml new file mode 100644 index 0000000..3c5de84 --- /dev/null +++ b/.github/workflows/harden-ci-security.yml @@ -0,0 +1,21 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json + +name: Harden CI security + +on: + workflow_call: + inputs: + target: + required: true + type: string + +jobs: + ensure-sha-pinned-actions: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + with: + ref: ${{ inputs.target }} + - name: Ensure all actions are pinned to a specific commit + uses: zgosalvez/github-actions-ensure-sha-pinned-actions@b88cd0aad2c36a63e42c71f81cb1958fed95ac87 # v3.0.10 diff --git a/.github/workflows/on-push-master.yml b/.github/workflows/on-push-master.yml new file mode 100644 index 0000000..8a53b2a --- /dev/null +++ b/.github/workflows/on-push-master.yml @@ -0,0 +1,22 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json + +name: On push to master branch + +on: + push: + branches: [master] + paths-ignore: + - ".github/**" + - "*.md" + +jobs: + run-tests: + uses: ./.github/workflows/run-tests.yml + with: + target: ${{ github.event.ref }} + + publish-release: + uses: ./.github/workflows/publish-release.yml + with: + target: ${{ github.event.ref }} + tag: latest diff --git a/.github/workflows/on-push-pr.yml b/.github/workflows/on-push-pr.yml new file mode 100644 index 0000000..0c44375 --- /dev/null +++ b/.github/workflows/on-push-pr.yml @@ -0,0 +1,17 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json + +name: On push to a PR + +on: + pull_request: + +jobs: + harden-ci-security: + uses: ./.github/workflows/harden-ci-security.yml + with: + target: ${{ github.event.pull_request.head.sha }} + + run-tests-for-pr: + uses: ./.github/workflows/run-tests.yml + with: + target: ${{ github.event.pull_request.head.sha }} diff --git a/.github/workflows/on-update-dot-github.yml b/.github/workflows/on-update-dot-github.yml new file mode 100644 index 0000000..4b27c59 --- /dev/null +++ b/.github/workflows/on-update-dot-github.yml @@ -0,0 +1,14 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json + +name: On changes to .github + +on: + push: + paths-ignore: + - "./.github/**" + +jobs: + harden-ci-security: + uses: ./.github/workflows/harden-ci-security.yml + with: + target: ${{ github.event.ref }} diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml new file mode 100644 index 0000000..34fc5bf --- /dev/null +++ b/.github/workflows/publish-release.yml @@ -0,0 +1,68 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json + +name: Publish release + +on: + workflow_call: + inputs: + target: + description: "The git ref to checkout, build from and release" + required: true + type: string + tag: + description: "The tag of the release" + required: true + type: string + prerelease: + description: "Prerelease" + required: false + default: false + type: boolean + +env: + CI_DIR: 2049ef39-42a2-46d2-b513-ee6d2e3a7b15 + +jobs: + build: + uses: ./.github/workflows/build.yml + with: + target: ${{ inputs.target }} + + publish-release: + runs-on: ubuntu-latest + needs: [build] + steps: + - name: Download build artifacts + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 + with: + name: build + path: ${{ env.CI_DIR }} + + - name: Extract build artifacts + run: | + artifacts_dir="$(realpath -m "$CI_DIR/artifacts")" + mkdir -p "$artifacts_dir" + tar -xzf "$CI_DIR/build.tar.gz" -C "$artifacts_dir" + rm "$CI_DIR/build.tar.gz" + + - name: Copy Binaries + run: | + artifacts_dir="$(realpath -m "$CI_DIR/artifacts")" + cp "${artifacts_dir}/win-x64/Luatrauma.AutoUpdater.exe" "${CI_DIR}/Luatrauma.AutoUpdater.win-x64.exe" + cp "${artifacts_dir}/linux-x64/Luatrauma.AutoUpdater" "${CI_DIR}/Luatrauma.AutoUpdater.linux-x64" + cp "${artifacts_dir}/osx-x64/Luatrauma.AutoUpdater" "${CI_DIR}/Luatrauma.AutoUpdater.osx-x64" + ls "${artifacts_dir}" + + - name: Publish release + uses: notpeelz/action-gh-create-release@c1bebd17c8a128e8db4165a68be4dc4e3f106ff1 # v5.0.1 + with: + target: ${{ inputs.target }} + tag: ${{ inputs.tag }} + prerelease: ${{ inputs.prerelease }} + strategy: replace + title: "Automatic build" + body: "Automatic build" + files: | + ${{ env.CI_DIR }}/Luatrauma.AutoUpdater.win-x64.exe + ${{ env.CI_DIR }}/Luatrauma.AutoUpdater.linux-x64 + ${{ env.CI_DIR }}/Luatrauma.AutoUpdater.osx-x64 diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml new file mode 100644 index 0000000..c082c4f --- /dev/null +++ b/.github/workflows/run-tests.yml @@ -0,0 +1,43 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json + +name: Run tests + +on: + workflow_call: + inputs: + target: + required: true + type: string + +jobs: + run-tests: + runs-on: ubuntu-latest + steps: + - name: Checkout branch + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + with: + repository: ${{ inputs.repository }} + ref: ${{ inputs.target }} + submodules: recursive + + - name: Setup .NET + uses: actions/setup-dotnet@6bd8b7f7774af54e05809fcc5431931b3eb1ddee # v4.0.1 + with: + dotnet-version: | + 6.0.x + + - name: Run tests + continue-on-error: true + run: | + set +e + dotnet test Luatrauma.AutoUpdater.sln -clp:"ErrorsOnly;Summary" --logger "trx;LogFileName=$PWD/test-results.trx" + echo "EXITCODE=$?" >> "$GITHUB_ENV" + + - name: Upload test results + uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 + with: + name: test-results + path: test-results.trx + + - name: Set exit code + run: exit "$EXITCODE" diff --git a/Deploy/DeployAll.sh b/Deploy/DeployAll.sh new file mode 100644 index 0000000..1fd9c9b --- /dev/null +++ b/Deploy/DeployAll.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +dotnet publish ../Luatrauma.AutoUpdater/Luatrauma.AutoUpdater.csproj -c Release --self-contained -r win-x64 -o bin/win-x64 -p:PublishSingleFile=true -p:PublishTrimmed=True -p:TrimMode=Link +dotnet publish ../Luatrauma.AutoUpdater/Luatrauma.AutoUpdater.csproj -c Release --self-contained -r linux-x64 -o bin/linux-x64 -p:PublishSingleFile=true -p:PublishTrimmed=True -p:TrimMode=Link +dotnet publish ../Luatrauma.AutoUpdater/Luatrauma.AutoUpdater.csproj -c Release --self-contained -r osx-x64 -o bin/osx-x64 -p:PublishSingleFile=true -p:PublishTrimmed=True -p:TrimMode=Link \ No newline at end of file