diff --git a/.github/dependabot.yml b/.github/dependabot.yml index d0f00c8..7022db5 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,3 +5,9 @@ updates: schedule: interval: daily time: "11:00" +- package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: daily + time: "11:00" + open-pull-requests-limit: 10 diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index eb65a75..781e981 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -7,20 +7,55 @@ on: branches: [ "master" ] jobs: + go-versions: + name: Lookup Go versions + runs-on: ubuntu-latest + permissions: + contents: read + outputs: + matrix: ${{ steps.versions.outputs.matrix }} + steps: + - uses: actions/checkout@v6 + - uses: arnested/go-version-action@6343454db06c63467680c5dc1f4f382fe9fe6303 + id: versions build: + name: Test + permissions: + contents: read runs-on: ubuntu-latest + needs: go-versions + strategy: + matrix: + version: ${{ fromJSON(needs.go-versions.outputs.matrix) }} steps: - uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v5 with: - go-version: stable + go-version: ${{ matrix.version }} check-latest: true + - name: Go Version + run: go version + - name: Build run: go build -v ./... - name: Test - run: go run github.com/onsi/ginkgo/v2/ginkgo -v -r --randomize-suites --randomize-all -race + run: make test + + - name: GoReleaser Check + uses: goreleaser/goreleaser-action@v6 + with: + version: '~> v2' + args: check + workdir: . + + - name: GoReleaser Build + uses: goreleaser/goreleaser-action@v6 + with: + version: '~> v2' + args: build --snapshot --clean --single-target --output . + workdir: . \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d9ba647..9e07dc1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,9 +1,10 @@ name: Ship Release +run-name: "Ship ${{ github.event.inputs.release_type }} Release" on: workflow_dispatch: inputs: - bump_type: + release_type: description: 'Type of version bump (major, minor, or patch)' required: true type: choice @@ -13,87 +14,43 @@ on: - minor - patch -run-name: "Ship ${{ inputs.bump_type }} Release" - -permissions: - contents: write - packages: write - jobs: - versions: - name: Set Version and Tag + release: + name: Release Go Binary runs-on: ubuntu-latest - outputs: - version: ${{ steps.bump_semver.outputs.version }} - tag: ${{ steps.bump_semver.outputs.tag }} + permissions: + contents: write steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@v4 with: fetch-depth: 0 - ref: ${{ github.ref_name }} + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: stable - - name: Get Latest Tag - id: get_latest_tag - run: | - version_prefix=${{ inputs.version_prefix }} - tag=$(git tag -l "v${version_prefix}.*" --sort=-v:refname | head -n 1) - tag=${tag:-v${version_prefix}.0.0} - echo "tag=${tag}" >> $GITHUB_OUTPUT - echo "🤔 *Previous tag: ${tag}*" >> $GITHUB_STEP_SUMMARY + - name: Go Version + run: go version - - name: Set Version and Tag - id: bump_semver + - name: Create Tag + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - set -e - tag="${{ steps.get_latest_tag.outputs.tag }}" - # Remove leading 'v' - version=${tag#v} - # Split into major, minor, and patch - IFS=. read -r major minor patch <> $GITHUB_OUTPUT - echo "tag=${new_tag}" >> $GITHUB_OUTPUT - echo "### 👷 Building ${new_version}" >> $GITHUB_STEP_SUMMARY - - - name: Create and Push Tag - run: | - git config --global user.email "identity-uaa+ci@pivotal.io" - git config --global user.name "UAA Identity Bot" - git tag "${{ steps.bump_semver.outputs.tag }}" - git push origin "${{ steps.bump_semver.outputs.tag }}" - echo "🏷️ *Created and pushed tag: ${{ steps.bump_semver.outputs.tag }}*" >> $GITHUB_STEP_SUMMARY - - releases-matrix: - name: Release Go Binary - runs-on: ubuntu-latest - needs: versions - strategy: - matrix: - # build and publish in parallel: linux/386, linux/amd64, linux/arm64, windows/386, windows/amd64, darwin/amd64, darwin/arm64 - goos: [ linux, windows, darwin ] - goarch: [ "386", amd64, arm64 ] - exclude: - - goarch: "386" - goos: darwin - - goarch: arm64 - goos: windows - steps: - - uses: actions/checkout@v4 - - uses: wangyoucao577/go-release-action@v1 + go install github.com/caarlos0/svu/v3@latest + release_type=${{ github.event.inputs.release_type }} + release_type=${release_type:-patch} + tag=$(svu ${release_type}) + echo "tag: $tag" + git tag "$tag" + git push --tags + + - name: GoReleaser Release + uses: goreleaser/goreleaser-action@v6 with: - github_token: ${{ secrets.GITHUB_TOKEN }} - goos: ${{ matrix.goos }} - goarch: ${{ matrix.goarch }} - build_command: "make" - build_flags: "build VERSION=${{ needs.versions.outputs.version }}" - binary_name: "build/uaa" - ldflags: "-I." + distribution: goreleaser + version: latest + args: release --clean + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index de44f84..29cc34e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,6 @@ .idea/ .vscode/ uaa-cli +uaa build/ +dist/ diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000..62d8858 --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,71 @@ +# The lines below are called `modelines`. See `:help modeline` +# Feel free to remove those if you don't want/need to use them. +# yaml-language-server: $schema=https://goreleaser.com/static/schema.json +# vim: set ts=2 sw=2 tw=0 fo=cnqoj + +version: 2 + +before: + hooks: + - go mod tidy + +builds: + - env: + - CGO_ENABLED=0 + goos: + - linux + - windows + - darwin + ldflags: + - -s -w + - -X code.cloudfoundry.org/uaa-cli/version.Version={{.Version}} + - -X code.cloudfoundry.org/uaa-cli/version.Commit={{.ShortCommit}} + binary: uaa + +archives: + - formats: [binary] + # Use same naming convention as before: uaa-{os}-{arch}-{version} + name_template: >- + uaa- + {{- .Os }}- + {{- if eq .Arch "amd64" }}amd64 + {{- else if eq .Arch "arm64" }}arm64 + {{- else if eq .Arch "386" }}386 + {{- else }}{{ .Arch }}{{ end }}- + {{- .Version }} + +release: + # Repository to release to. + github: + owner: cloudfoundry + name: uaa-cli + + # You can change the name of the release. + name_template: "UAA CLI Release {{.Version}}" + + # If set to auto, will mark the release as not ready for production + # in case there is an indicator for this in the tag e.g. v1.0.0-rc1 + prerelease: auto + + # What to do with the release notes in case there the release already exists. + mode: replace + +checksum: + name_template: 'checksums.txt' + +snapshot: + version_template: "{{ .Branch }}-{{ .ShortCommit }}" + +changelog: + # This automatically uses PRs merged since the last tag + # Shows clickable PR links (#123) and usernames (@user) + use: github-native + +# Uncomment if you want to publish to a package manager +# brews: +# - name: uaa-cli +# homepage: https://github.com/cloudfoundry/uaa-cli +# description: "A command line client for the CloudFoundry UAA API" +# repository: +# owner: cloudfoundry +# name: homebrew-tap \ No newline at end of file diff --git a/Makefile b/Makefile index 99eb0ff..03e7a9a 100644 --- a/Makefile +++ b/Makefile @@ -1,45 +1,52 @@ -.PHONY: all build ci clean format ginkgo test install - -BUILD_DEST = build/uaa +EXECUTABLE_NAME = uaa INSTALL_DEST = $(GOPATH)/bin/uaa -COMMIT_HASH=$(shell git rev-parse --short HEAD) -GOFILES=$(shell find . -type f -name '*.go') -ifndef VERSION - VERSION = DEV -endif +.PHONY: all +all: format test build ## Runs: Format, Test, and Build + +${EXECUTABLE_NAME}: **/*.go go.mod go.sum ## Build + goreleaser build --snapshot --clean --single-target --output . + +**/*.go: + @# noop -GOFLAGS := -v -ldflags "-X code.cloudfoundry.org/uaa-cli/version.Version=${VERSION} -X code.cloudfoundry.org/uaa-cli/version.Commit=${COMMIT_HASH}" +.PHONY: build +build: ${EXECUTABLE_NAME} ## Build -all: test clean build +.PHONY: build_all +build_all: **/*.go go.mod go.sum ## Build all releases, in dist, using Goreleaser (requires goreleaser to be installed) + goreleaser build --snapshot --clean -clean: - rm -rf build +.PHONY: clean +clean: ## Clean up artifacts + rm -rf build/ dist/ ${EXECUTABLE_NAME} -format: +.PHONY: format +format: ## Format Go Code go fmt ./... -ginkgo: +.PHONY: test +test: ## Run Ginkgo tests go run github.com/onsi/ginkgo/v2/ginkgo -v -r --randomize-suites --randomize-all -race -test: format ginkgo +.PHONY: goreleaser-check +goreleaser-check: ## Test goreleaser configuration + goreleaser check -ci: ginkgo - -build: - mkdir -p build - CGO_ENABLED=0 go build $(GOFLAGS) -o $(BUILD_DEST) +.PHONY: install +install: ${EXECUTABLE_NAME} ## Install executable + rm -rf $(INSTALL_DEST) + cp ${EXECUTABLE_NAME} $(INSTALL_DEST) -build_all: - mkdir -p build - CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build $(GOFLAGS) -o $(BUILD_DEST)-darwin-arm64 - CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build $(GOFLAGS) -o $(BUILD_DEST)-darwin-amd64 - CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build $(GOFLAGS) -o $(BUILD_DEST)-linux-amd64 - CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build $(GOFLAGS) -o $(BUILD_DEST)-windows-amd64 +.PHONY: cve +cve: ${EXECUTABLE_NAME} ## Scan for CVEs + grype file:${EXECUTABLE_NAME} -install: - rm -rf $(INSTALL_DEST) - cp $(BUILD_DEST) $(INSTALL_DEST) +.PHONY: setup +setup: ## Setup packages needed for release + brew install caarlos0/tap/svu + brew install goreleaser/tap/goreleaser -cve: build - grype file:$(BUILD_DEST) \ No newline at end of file +.PHONY: help +help: ## Display this help + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) \ No newline at end of file