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

feat: support chocolatey #43

Draft
wants to merge 16 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
190 changes: 183 additions & 7 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,35 @@ on:
go-version:
required: true
type: string
runs-on:
required: false
type: string
default: '"ubuntu-latest"'
description: |
JSON string for runs-on.
e.g.
runs-on: '"macos-latest"'
runs-on: '["foo"]'
winget_head_repo:
required: false
type: string
winget_base_repo:
required: false
default: microsoft/winget-pkgs
type: string
winget_new:
required: false
default: false
type: boolean
secrets:
gh_app_id:
required: false
gh_app_private_key:
required: false
chocolatey_api_key:
required: false
github_token_for_winget:
required: false

permissions: {}

Expand All @@ -33,9 +57,11 @@ env:

jobs:
build:
runs-on: ubuntu-latest
runs-on: ${{fromJSON(inputs.runs-on)}}
outputs:
hashes: ${{ steps.hash.outputs.hashes }}
prerelease: ${{ steps.prerelease.outputs.value }}
winget: ${{ steps.github_token_for_winget.outputs.has }}
permissions:
contents: write # required to create a release
id-token: write # required for cosign
Expand All @@ -51,9 +77,55 @@ jobs:
aqua_version: ${{inputs.aqua_version}}
policy_allow: ${{inputs.aqua_policy_allow}}

- name: Check App ID
id: app_id
env:
APP_ID: ${{ secrets.gh_app_id }}
run: |
if [ -n "$APP_ID" ]; then
has=true
else
has=false
fi
echo "has=$has" >> "$GITHUB_OUTPUT"

- name: Check secrets.GH_TOKEN_FOR_WINGET
id: github_token_for_winget
env:
GH_TOKEN_FOR_WINGET: ${{ secrets.github_token_for_winget }}
run: |
if [ -n "$GH_TOKEN_FOR_WINGET" ]; then
has=true
else
has=false
fi
echo "has=$has" >> "$GITHUB_OUTPUT"

- name: Check secrets.CHOCOLATEY_API_KEY
id: chocolatey
env:
CHOCOLATEY_API_KEY: ${{ secrets.CHOCOLATEY_API_KEY }}
run: |
if [ -n "$CHOCOLATEY_API_KEY" ]; then
has=true
else
has=false
fi
echo "has=$has" >> "$GITHUB_OUTPUT"

- name: Check if the version is a prerelease
id: prerelease
run: |
if [[ "$GITHUB_REF_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
value=false
else
value=true
fi
echo "value=$value" >> "$GITHUB_OUTPUT"

- name: Generate token
id: generate_token
if: inputs.homebrew
if: steps.app_id.outputs.has == 'true'
uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a # v2.1.0
with:
app_id: ${{ secrets.gh_app_id }}
Expand All @@ -68,19 +140,28 @@ jobs:
run: git fetch --prune --unshallow
- run: cosign version

- name: Run GoReleaser
run: goreleaser release --clean
if: inputs.homebrew
- name: Set envs
if: steps.prerelease.outputs.value != 'true'
run: |
if [ -n "$CHOCOLATEY_API_KEY" ]; then
echo "CHOCOLATEY_API_KEY=$CHOCOLATEY_API_KEY" >> "$GITHUB_ENV"
fi
if [ -n "$HOMEBREW_TAP_GITHUB_TOKEN" ]; then
echo "HOMEBREW_TAP_GITHUB_TOKEN=$HOMEBREW_TAP_GITHUB_TOKEN" >> "$GITHUB_ENV"
fi
env:
GITHUB_TOKEN: ${{ github.token }}
CHOCOLATEY_API_KEY: ${{ secrets.CHOCOLATEY_API_KEY }}
HOMEBREW_TAP_GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}

- name: Run GoReleaser
run: goreleaser release --clean
if: "! inputs.homebrew"
if: inputs.homebrew
env:
GITHUB_TOKEN: ${{ github.token }}

- name: Clear envs
run: echo "" > "$GITHUB_ENV"

- name: Generate hashes
id: hash
run: |
Expand All @@ -89,6 +170,12 @@ jobs:
# sha256sum artifact1 artifact2 ... | base64 -w0
echo "hashes=$((find dist -name "*.tar.gz" && find dist -name "*.zip") | xargs sha256sum | base64 -w0)" >> "$GITHUB_OUTPUT"

- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
if: steps.prerelease.outputs.value != 'true' && steps.github_token_for_winget.outputs.has == 'true'
with:
name: winget
path: dist/winget

provenance:
needs: [build]
permissions:
Expand All @@ -103,3 +190,92 @@ jobs:
base64-subjects: "${{ needs.build.outputs.hashes }}"
# Upload provenance to a new release
upload-assets: true

winget:
needs: [build]
runs-on: ubuntu-latest
if: needs.build.outputs.winget == 'true' && needs.build.outputs.prerelease != 'true'
permissions: {}
steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- uses: aquaproj/aqua-installer@36dc5833b04eb63f06e3bb818aa6b7a6e6db99a9 # v2.1.2
with:
aqua_version: ${{inputs.aqua_version}}
policy_allow: ${{inputs.aqua_policy_allow}}

- name: Generate token
id: generate_token
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 # v1.8.0
with:
app_id: ${{ secrets.gh_app_id }}
private_key: ${{ secrets.gh_app_private_key }}

- uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
with:
name: winget

- name: Get parameters to send a pull request to winget-pkgs
# manifests/<first lower case letter of publisher>/<publisher>/<package>/<version>/
id: winget
run: |
set -euo pipefail

echo "head_repo=${HEAD_REPO:-${GITHUB_REPOSITORY_OWNER}/winget-pkgs}" >> "$GITHUB_OUTPUT"

cd dist/winget

pkg_id=$(find manifests -type f | grep -E "\.yaml$" |
sed "s|^manifests/./||" |
head -n 1 |
xargs -n 1 dirname)

a=${pkg_id#*/}
publisher=${pkg_id%%/*}
pkg_name=${a%/*}
version=${pkg_id##*/}

echo "branch=$pkg_id" >> "$GITHUB_OUTPUT"
echo "publisher=$publisher" >> "$GITHUB_OUTPUT"
echo "pkg_name=$pkg_name" >> "$GITHUB_OUTPUT"
echo "version=$version" >> "$GITHUB_OUTPUT"

title_prefix=Update
if [ "$WINGET_NEW" = true ]; then
title_prefix=New
fi
title="$title_prefix version: ${publisher}.${pkg_name} ${version}"
echo "title=$title" >> "$GITHUB_OUTPUT"
env:
WINGET_TOKEN: ${{ secrets.github_token_for_winget }}
BASE_REPO: ${{ inputs.winget_base_repo }}
HEAD_REPO: ${{ inputs.winget_head_repo }}
WINGET_NEW: ${{ inputs.winget_new }}

- name: Push winget manifest to a remote branch
if: steps.winget.outputs.branch != ''
run: |
set -euo pipefail

cd dist/winget
find manifests -type f | grep -E "\.yaml$" |
xargs ghcp commit -r "$REPO" -b "$BRANCH" -m "$COMMIT_MESSAGE"
env:
BRANCH: ${{ steps.winget.outputs.branch }}
COMMIT_MESSAGE: ${{ steps.winget.outputs.title }}
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
REPO: ${{ steps.winget.outputs.head_repo }}

- name: Create a pull request to winget-pkgs
if: steps.winget.outputs.branch != ''
run: |
sleep 5
body="This pull request was created by [GitHub Actions](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}).
The manifests were generated by [GoReleaser](https://goreleaser.com/customization/winget/)."
ghcp pull-request -r "$HEAD_REPO" -b "$BRANCH" --base-repo "$BASE_REPO" --title "$TITLE" --body "$body"
# gh -R "$BASE_REPO" pr create -H "$HEAD_REPO" --title "$TITLE"
env:
BRANCH: ${{ steps.winget.outputs.branch }}
TITLE: ${{ steps.winget.outputs.title }}
GITHUB_TOKEN: ${{ secrets.github_token_for_winget }}
BASE_REPO: ${{ inputs.winget_base_repo }}
HEAD_REPO: ${{ steps.winget.outputs.head_repo }}