Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Modulectl release #61

Merged
merged 15 commits into from
Oct 15, 2024
36 changes: 36 additions & 0 deletions .github/scripts/create_changelog.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env bash


set -o errexit
set -E
set -o pipefail

CURRENT_RELEASE_TAG=$1
DOCKER_IMAGE_URL=$2
LAST_RELEASE_TAG=$3

if [ "${LAST_RELEASE_TAG}" == "" ]
then
LAST_RELEASE_TAG=$(git describe --tags --abbrev=0)
fi

GITHUB_URL=https://api.github.com/repos/$CODE_REPOSITORY
GITHUB_AUTH_HEADER="Authorization: Bearer $GITHUB_TOKEN"
CHANGELOG_FILE="CHANGELOG.md"

git log "$LAST_RELEASE_TAG"..HEAD --pretty=tformat:"%h" --reverse | while read -r commit
do
COMMIT_AUTHOR=$(curl -H "$GITHUB_AUTH_HEADER" -sS "$GITHUB_URL"/commits/"$commit" | jq -r '.author.login')
if [ "${COMMIT_AUTHOR}" != "kyma-bot" ]; then
git show -s "${commit}" --format="* %s by @${COMMIT_AUTHOR}" >> ${CHANGELOG_FILE}
fi
done

{
echo -e "\n**Full changelog**: $GITHUB_URL/compare/$LAST_RELEASE_TAG...$CURRENT_RELEASE_TAG"
echo -e "\n"
echo "## Docker image URL"
echo "$DOCKER_IMAGE_URL"
} >> $CHANGELOG_FILE

cat $CHANGELOG_FILE
34 changes: 34 additions & 0 deletions .github/scripts/draft_release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/env bash

set -o nounset
set -o errexit
set -E
set -o pipefail

RELEASE_TAG=$1

GITHUB_URL=https://api.github.com/repos/${CODE_REPOSITORY}
GITHUB_AUTH_HEADER="Authorization: Bearer ${GITHUB_TOKEN}"
CHANGELOG_FILE=$(cat CHANGELOG.md)

JSON_PAYLOAD=$(jq -n \
--arg tag_name "$RELEASE_TAG" \
--arg name "$RELEASE_TAG" \
--arg body "$CHANGELOG_FILE" \
'{
"tag_name": $tag_name,
"name": $name,
"body": $body,
"draft": true
}')

CURL_RESPONSE=$(curl -L \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "${GITHUB_AUTH_HEADER}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"${GITHUB_URL}"/releases \
-d "$JSON_PAYLOAD")

# return the id of the release draft
echo "$CURL_RESPONSE" | jq -r ".id"
25 changes: 25 additions & 0 deletions .github/scripts/get_release_by_tag.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env bash

set -o nounset
set -o pipefail

RELEASE_TAG=$1
GITHUB_TOKEN=$2

GITHUB_URL=https://api.github.com/repos/$CODE_REPOSITORY
GITHUB_AUTH_HEADER="Authorization: Bearer $GITHUB_TOKEN"

curl -L \
-s \
--fail-with-body \
-H "Accept: application/vnd.github+json" \
-H "$GITHUB_AUTH_HEADER" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"$GITHUB_URL"/releases/tags/"$RELEASE_TAG"

CURL_EXIT_CODE=$?

if [[ $CURL_EXIT_CODE == 0 ]]; then
echo "Release with tag $RELEASE_TAG already exists!"
exit 1
fi
20 changes: 20 additions & 0 deletions .github/scripts/publish_release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env bash

set -o nounset
set -o errexit
set -E
set -o pipefail

RELEASE_ID=$1

GITHUB_URL=https://api.github.com/repos/${CODE_REPOSITORY}
GITHUB_AUTH_HEADER="Authorization: Bearer ${GITHUB_TOKEN}"

CURL_RESPONSE=$(curl -L \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "${GITHUB_AUTH_HEADER}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"${GITHUB_URL}"/releases/"${RELEASE_ID}" \
-d '{"draft":false}')
echo "$CURL_RESPONSE"
58 changes: 58 additions & 0 deletions .github/scripts/upload_assets.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/usr/bin/env bash

set -o nounset
set -o errexit
set -E
set -o pipefail

uploadFile() {
filePath=${1}
ghAsset=${2}

echo "Uploading ${filePath} as ${ghAsset}"
response=$(curl -s -o output.txt -w "%{http_code}" \
--request POST --data-binary @"$filePath" \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Content-Type: text/yaml" \
"$ghAsset")
if [[ "$response" != "201" ]]; then
echo "Unable to upload the asset ($filePath): "
echo "HTTP Status: $response"
cat output.txt
exit 1
else
echo "$filePath uploaded"
fi
}

echo "PULL_BASE_REF= ${PULL_BASE_REF}"

echo "Fetching releases"
CURL_RESPONSE=$(curl -w "%{http_code}" -sL \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $GITHUB_TOKEN"\
https://api.github.com/repos/kyma-project/modulectl/releases)
JSON_RESPONSE=$(sed '$ d' <<< "${CURL_RESPONSE}")
HTTP_CODE=$(tail -n1 <<< "${CURL_RESPONSE}")
if [[ "${HTTP_CODE}" != "200" ]]; then
echo "${CURL_RESPONSE}"
exit 1
fi

echo "Finding release id for: ${PULL_BASE_REF}"
RELEASE_ID=$(jq <<< "${JSON_RESPONSE}" --arg tag "${PULL_BASE_REF}" '.[] | select(.tag_name == $ARGS.named.tag) | .id')

echo "Got '${RELEASE_ID}' release id"
if [ -z "${RELEASE_ID}" ]
then
echo "No release with tag = ${PULL_BASE_REF}"
exit 1
fi

echo "Adding assets to Github release"
UPLOAD_URL="https://uploads.github.com/repos/kyma-project/modulectl/releases/${RELEASE_ID}/assets"

echo "$UPLOAD_URL"
pwd
ls -la
uploadFile "modulectl-linux" "${UPLOAD_URL}?name=modulectl-linux"
15 changes: 15 additions & 0 deletions .github/scripts/validate_release_tag.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env bash

set -o nounset
set -o errexit
set -E
set -o pipefail

CURRENT_RELEASE_TAG=$1

semver_pattern="^([0-9]|[1-9][0-9]*)[.]([0-9]|[1-9][0-9]*)[.]([0-9]|[1-9][0-9]*)(-[a-z][a-z0-9]*)?$"

if ! [[ $CURRENT_RELEASE_TAG =~ $semver_pattern ]]; then
echo "Given tag \"$CURRENT_RELEASE_TAG\" does not match semantic version pattern: \"$semver_pattern\"."
exit 1
fi
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ on:
pull_request:
branches:
- main
- 'release-**'
workflow_dispatch:
jobs:
build-modulectl:
Expand Down
81 changes: 81 additions & 0 deletions .github/workflows/create-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
name: "Create release"

on:
workflow_dispatch:
inputs:
version:
description: "Release version"
default: ""
required: true
since:
description: "Changelog since"
default: ""
required: false

jobs:
validate-release:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Validate the release tag
run: ./.github/scripts/validate_release_tag.sh ${{ github.event.inputs.version }}
- name: Check if release exists
run: ./.github/scripts/get_release_by_tag.sh ${{ github.event.inputs.version }} ${{ secrets.GITHUB_TOKEN }}
draft-release:
runs-on: ubuntu-latest
needs: validate-release
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Create changelog
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./.github/scripts/create_changelog.sh ${{ github.event.inputs.version }} ${{ env.IMAGE_REPO }}:${{ github.event.inputs.version }} ${{ github.event.inputs.since }}
- name: Draft release
id: draft-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
RELEASE_ID=$(./.github/scripts/draft_release.sh ${{ github.event.inputs.version }})
echo "release_id=$RELEASE_ID" >> $GITHUB_OUTPUT
- name: Create tag
run: |
git tag ${{ github.event.inputs.version }}
git push origin ${{ github.event.inputs.version }} --tags
outputs:
release_id: ${{ steps.draft-release.outputs.release_id }}
artifacts:
runs-on: ubuntu-latest
needs: validate-release
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Go setup
uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
cache-dependency-path: 'go.sum'
- name: "Run 'make build' with version"
run: make build VERSION=${{ inputs.version }}
- name: Add binaries to draft
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PULL_BASE_REF: ${{ github.event.inputs.version }}
run: ./.github/scripts/upload_assets.sh
publish-release:
runs-on: ubuntu-latest
needs: [ validate-release, draft-release, artifacts ]
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Publish release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./.github/scripts/publish_release.sh ${{ needs.draft-release.outputs.release_id }}
File renamed without changes.
9 changes: 1 addition & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,14 @@ FLAGS = -ldflags '-s -w -X github.com/kyma-project/modulectl/cmd/modulectl/versi
validate-docs:
./hack/verify-generated-docs.sh

build: build-windows build-linux build-darwin build-windows-arm build-linux-arm build-darwin-arm

build-windows:
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o ./bin/modulectl.exe $(FLAGS) ./cmd
build: build-linux build-darwin build-linux-arm build-darwin-arm

build-darwin:
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -o ./bin/modulectl-darwin $(FLAGS) ./cmd

build-linux:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o ./bin/modulectl-linux $(FLAGS) ./cmd

# ARM based chipsets
build-windows-arm:
CGO_ENABLED=0 GOOS=windows GOARCH=arm64 go build -o ./bin/modulectl-arm.exe $(FLAGS) ./cmd

build-darwin-arm:
CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -o ./bin/modulectl-darwin-arm $(FLAGS) ./cmd

Expand Down
2 changes: 1 addition & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func main() {
os.Exit(-1)
}

if err := cmd.Execute(); err != nil {
if err = cmd.Execute(); err != nil {
fmt.Println(fmt.Errorf("failed to execute modulectl command: %w", err))
os.Exit(-1)
}
Expand Down
7 changes: 7 additions & 0 deletions cmd/modulectl/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

createcmd "github.com/kyma-project/modulectl/cmd/modulectl/create"
scaffoldcmd "github.com/kyma-project/modulectl/cmd/modulectl/scaffold"
"github.com/kyma-project/modulectl/cmd/modulectl/version"
"github.com/kyma-project/modulectl/internal/service/componentarchive"
"github.com/kyma-project/modulectl/internal/service/componentdescriptor"
"github.com/kyma-project/modulectl/internal/service/contentprovider"
Expand Down Expand Up @@ -72,8 +73,14 @@ func NewCmd() (*cobra.Command, error) {
return nil, fmt.Errorf("failed to build create command: %w", err)
}

versionCmd, err := version.NewCmd()
if err != nil {
return nil, fmt.Errorf("failed to build version command: %w", err)
}

rootCmd.AddCommand(scaffoldCmd)
rootCmd.AddCommand(createCmd)
rootCmd.AddCommand(versionCmd)

return rootCmd, nil
}
Expand Down
29 changes: 29 additions & 0 deletions cmd/modulectl/version/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package version

import (
"github.com/spf13/cobra"
)

const (
use = "version"
short = "Prints the current modulectl version."
long = "This command prints the current semantic version of the modulectl binary set at build time."
)

// Version will contain the binary version injected by make build target
var Version string //nolint:gochecknoglobals // This is a variable meant to be set at build time

func NewCmd() (*cobra.Command, error) {
cmd := &cobra.Command{
Use: use,
Short: short,
Long: long,
Args: cobra.NoArgs,
Aliases: []string{"v"},
Run: func(cmd *cobra.Command, args []string) {
cmd.Println(Version)
},
}

return cmd, nil
}
Loading
Loading