Skip to content

Commit

Permalink
ci(releases): add release automation
Browse files Browse the repository at this point in the history
  • Loading branch information
MEhrn00 committed Mar 17, 2024
1 parent d38aa47 commit 3ac7905
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 52 deletions.
172 changes: 120 additions & 52 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,57 +3,48 @@ name: Release
on:
push:
branches:
- 'release/v[0-9]+.[0-9]+.*'

paths:
- Payload_Type/thanatos/**
- config.json
- agent_capabilities.json
- main

env:
IMAGE_REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
IMAGE_DESCRIPTION: "Base container image for the Thanatos Mythic C2 agent"
IMAGE_LICENSE: BSD-3-Clause
AGENT_CODE: Payload_Type/thanatos/thanatos/agent_code
# Registry for the container image
CONTAINER_IMAGE_REGISTRY: ghcr.io
# Name of the container image
CONTAINER_IMAGE_NAME: ${{ github.repository }}
# Description of the base container image
CONTAINER_IMAGE_DESCRIPTION: "Base container image for the Thanatos Mythic C2 agent"
# License for the base container image
CONTAINER_IMAGE_LICENSE: BSD-3-Clause
# Path to the agent code
AGENT_CODE_PATH: Payload_Type/thanatos/thanatos/agent_code

jobs:
lint-workflow:
name: Lint
uses: ./.github/workflows/lint.yml

build-container:
name: Build and push the base container image
needs: lint-workflow
# Get the new release version number
version:
name: Get the new release version
runs-on: ubuntu-latest

permissions:
contents: read
packages: write
outputs:
release: ${{ steps.release.number }}

steps:
- name: Checkout the repository
uses: actions/checkout@v4

- name: Get the release version from the branch name
- name: Get the latest release version from the changelog
run: echo "RELEASE_VERSION=$(python .github/scripts/changelogtool.py latest)" >> $GITHUB_ENV

- name: Verify that a tag with this version does not already exist
run: |
GIT_BRANCH=${GITHUB_BASE_REF:-${GITHUB_REF#refs/heads/}}
VERSION=$(echo $GIT_BRANCH | grep --color=never -Eo '[0-9]+\.[0-9]+\.[0-9]+')
echo "VERSION=$VERSION" >> $GITHUB_ENV
git tag -l | grep $RELEASE_VERSION
test $? -eq 0 && { echo "Tag for release $RELEASE_VERSION already exists"; exit 1 } || exit 0
- name: Build and push the container
uses: ./.github/actions/build-container
with:
image-registry: ${{ env.IMAGE_REGISTRY }}
image-name: ${{ env.IMAGE_NAME }}
image-tag: v${{ env.VERSION }}
image-description: ${{ env.IMAGE_DESCRIPTION }}
image-license: ${{ env.IMAGE_LICENSE }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Store the new release version number
id: release
run: echo "number=${RELEASE_VERSION#v}" >> $GITHUB_OUTPUT

version:
bump:
name: Bump repository version numbers
needs: build-container
needs: version
runs-on: ubuntu-latest

permissions:
Expand All @@ -64,43 +55,120 @@ jobs:
- name: Checkout the repository
uses: actions/checkout@v4

- name: Get the release version from the branch name
run: |
GIT_BRANCH=${GITHUB_BASE_REF:-${GITHUB_REF#refs/heads/}}
VERSION=$(echo $GIT_BRANCH | grep --color=never -Eo '[0-9]+\.[0-9]+\.[0-9]+')
echo "VERSION=$VERSION" >> $GITHUB_ENV
- name: Lowercase the container image name
run: echo "IMAGE_NAME=${IMAGE_NAME,,}" >> ${GITHUB_ENV}
run: echo "CONTAINER_IMAGE_NAME=${CONTAINER_IMAGE_NAME,,}" >> ${GITHUB_ENV}

- name: Set config.json version number
uses: jossef/[email protected]
with:
file: config.json
field: remote_images.thanatos
value: ${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}:v${{ env.VERSION }}
value: ${{ env.CONTAINER_IMAGE_REGISTRY }}/${{ env.CONTAINER_IMAGE_NAME }}:v${{ needs.version.release }}

- name: Set agent_capabilities.json version number
uses: jossef/[email protected]
with:
file: agent_capabilities.json
field: agent_version
value: ${{ env.VERSION }}
value: ${{ needs.version.release }}

- name: Set base Dockerfile image reference version number
- name: Set base Dockerfile image reference tag to match the version number
working-directory: Payload_Type/thanatos
run: sed -i "s|^FROM ghcr\.io.*$|FROM ${IMAGE_REGISTRY}/${IMAGE_NAME}:v${VERSION}|" Dockerfile
env:
VERSION: ${{ needs.version.number }}
run: sed -i "s|^FROM .*$|FROM ${CONTAINER_IMAGE_REGISTRY}/${CONTAINER_IMAGE_NAME}:v${VERSION}|" Dockerfile

- name: Set agent Cargo.toml version number
working-directory: ${{ env.AGENT_CODE }}
working-directory: ${{ env.AGENT_CODE_PATH }}
env:
VERSION: ${{ needs.version.number }}
run: sed -i "0,/^version = .*$/s//version = \"${VERSION}\"/" Cargo.toml

- name: Push the updated version number changes
uses: EndBug/add-and-commit@v9 # ref: https://github.com/marketplace/actions/add-commit
uses: EndBug/add-and-commit@v9
with:
add: "['config.json', 'agent_capabilities.json', 'Payload_Type/thanatos/Dockerfile', '${{ format(\'{0}/Cargo.toml\', env.AGENT_CODE) }}']"
add: "['config.json', 'agent_capabilities.json', 'Payload_Type/thanatos/Dockerfile', '${{ format('{0}/Cargo.toml', env.AGENT_CODE_PATH) }}']"
default_author: github_actions
committer_email: github-actions[bot]@users.noreply.github.com
message: "Bump version number to match release '${{ env.VERSION }}'"
new_branch: ${{ github.ref_name }}
message: "chore(release): bump version numbers to match release 'v${{ needs.version.release }}'"
pathspec_error_handling: exitImmediately

image:
name: Build the base container image
needs:
- version
- bump
runs-on: ubuntu-latest

permissions:
contents: read
packages: write

steps:
- name: Checkout the repository
uses: actions/checkout@v4

- name: Set the container image fully qualified url
run: echo "CONTAINER_IMAGE_URL=${CONTAINER_IMAGE_URL,,}" >> ${GITHUB_ENV}
env:
CONTAINER_IMAGE_URL: ${{ env.CONTAINER_IMAGE_REGISTRY }}/${{ env.CONTAINER_IMAGE_NAME }}:v${{ needs.version.release }}

- name: Log in to the container registry
uses: docker/login-action@v3
with:
registry: ${{ env.CONTAINER_IMAGE_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push the container image
uses: docker/build-push-action@v5
with:
context: Payload_Type/thanatos
file: Payload_Type/thanatos/.docker/Dockerfile
tags: ${{ env.CONTAINER_IMAGE_URL }}
push: true
labels: |
org.opencontainers.image.source=https://github.com/${{ github.repository }}
org.opencontainers.image.description=${{ env.CONTAINER_IMAGE_DESCRIPTION }}
org.opencontainers.image.licenses=${{ env.CONTAINER_IMAGE_LICENSE }}
release:
name: Create a new release
needs:
- version
- image
runs-on: ubuntu-latest

permissions:
contents: write
packages: read

steps:
- name: Checkout the repository
uses: actions/checkout@v4

- name: Create a new tag for the release
uses: EndBug/add-and-commit@v9
with:
message: "chore(release): Thanatos v${{ needs.version.release }}"
push: true
tag: "v${{ needs.version.release }}"
pathspec_error_handling: exitImmediately

- name: Create a new release
env:
VERSION: ${{ needs.version.release }}
run: |
RELEASE_BODY=$(python .github/scripts/changelogtool.py extract $VERSION)
gh api \
--method POST \
-H "Accept: application/vnd.github+json" \
-H "X-Github-Api-Version: 2022-11-28" \
/repos/${GITHUB_REPOSITORY}/releases \
-f tag_name='v${VERSION}' \
-f target_commitish="$GITHUB_REF_NAME" \
-f name="Thanatos v${VERSION}" \
-f body="$RELEASE_BODY" \
-F draft=false \
-F prerelease=false \
-F generate_release_notes=false
32 changes: 32 additions & 0 deletions .github/workflows/verify-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Verify release

on:
pull_request:
branches:
- main

jobs:
verify:
name: Verify release PR
if: ${{ contains(github.event.pull_request.labels.*.name, "release") }}
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Get the latest changelog entry
run: echo "LATEST_CHANGELOG=$(python .github/scripts/changelogtool.py)" >> $GITHUB_ENV

- name: Assert that a git tag does not exist for the latest entry
run: |
git tag -l | grep $LATEST_CHANGELOG
test $? -eq 0 && { echo "Git tag for changelog entry $LATEST_CHANGELOG already exists"; exit 1 } || exit 0
- name: Assert that a release does not already exist for the latest entry
run: |
gh api \
-H "Accept: application/vnd.github+json" \
-H "X-Github-Api-Version: 2022-11-28" \
/repos/MythicAgents/thanatos/releases/tags/${LATEST_CHANGELOG}
test $? -eq 0 && { echo "Release for changelog entry $LATEST_CHANGELOG already exists"; exit 1 } || exit 0

0 comments on commit 3ac7905

Please sign in to comment.