Skip to content
Merged
Show file tree
Hide file tree
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
65 changes: 65 additions & 0 deletions .github/workflows/publish-homebrew.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Publish Homebrew Formula

on:
workflow_call:
inputs:
plan:
required: true
type: string

jobs:
publish-homebrew-formula:
runs-on: ubuntu-22.04
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PLAN: ${{ inputs.plan }}
GITHUB_USER: "axo bot"
GITHUB_EMAIL: "admin+bot@axo.dev"
if: ${{ !fromJson(inputs.plan).announcement_is_prerelease || fromJson(inputs.plan).publish_prereleases }}
steps:
- uses: actions/checkout@v6
with:
persist-credentials: true
repository: "hotdata-dev/homebrew-tap"
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}

- name: Fetch homebrew formulae
uses: actions/download-artifact@v7
with:
pattern: artifacts-*
path: Formula/
merge-multiple: true

- name: Patch and commit formula files
run: |
git config --global user.name "${GITHUB_USER}"
git config --global user.email "${GITHUB_EMAIL}"

for release in $(echo "$PLAN" | jq --compact-output '.releases[] | select([.artifacts[] | endswith(".rb")] | any)'); do
filename=$(echo "$release" | jq '.artifacts[] | select(endswith(".rb"))' --raw-output)
name=$(echo "$filename" | sed "s/\.rb$//")
version=$(echo "$release" | jq .app_version --raw-output)

export PATH="/home/linuxbrew/.linuxbrew/bin:$PATH"
brew update
brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix "Formula/${filename}" || true

# Add shell completions generation if not already present
if ! grep -q 'generate_completions_from_executable' "Formula/${filename}"; then
sed -i '/bin\.install "hotdata"/a\ generate_completions_from_executable(bin/"hotdata", "completions")' "Formula/${filename}"
fi

git add "Formula/${filename}"
git commit -m "${name} ${version}"
done
git push

- name: Remove .rb from GitHub Release assets
run: |
TAG=$(echo "$PLAN" | jq -r '.announcement_tag')
if [ -z "$TAG" ] || [ "$TAG" = "null" ]; then
exit 0
fi
for asset in $(gh release view "$TAG" --repo hotdata-dev/hotdata-cli --json assets -q '.assets[].name' | grep '\.rb$'); do
gh release delete-asset "$TAG" "$asset" --repo hotdata-dev/hotdata-cli --yes
done
54 changes: 11 additions & 43 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -278,61 +278,29 @@ jobs:

gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/*

publish-homebrew-formula:
custom-publish-homebrew:
needs:
- plan
- host
runs-on: "ubuntu-22.04"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PLAN: ${{ needs.plan.outputs.val }}
GITHUB_USER: "axo bot"
GITHUB_EMAIL: "admin+bot@axo.dev"
if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}
steps:
- uses: actions/checkout@v6
with:
persist-credentials: true
repository: "hotdata-dev/homebrew-tap"
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
# So we have access to the formula
- name: Fetch homebrew formulae
uses: actions/download-artifact@v7
with:
pattern: artifacts-*
path: Formula/
merge-multiple: true
# This is extra complex because you can make your Formula name not match your app name
# so we need to find releases with a *.rb file, and publish with that filename.
- name: Commit formula files
run: |
git config --global user.name "${GITHUB_USER}"
git config --global user.email "${GITHUB_EMAIL}"

for release in $(echo "$PLAN" | jq --compact-output '.releases[] | select([.artifacts[] | endswith(".rb")] | any)'); do
filename=$(echo "$release" | jq '.artifacts[] | select(endswith(".rb"))' --raw-output)
name=$(echo "$filename" | sed "s/\.rb$//")
version=$(echo "$release" | jq .app_version --raw-output)

export PATH="/home/linuxbrew/.linuxbrew/bin:$PATH"
brew update
# We avoid reformatting user-provided data such as the app description and homepage.
brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix "Formula/${filename}" || true

git add "Formula/${filename}"
git commit -m "${name} ${version}"
done
git push
uses: ./.github/workflows/publish-homebrew.yml
with:
plan: ${{ needs.plan.outputs.val }}
secrets: inherit
# publish jobs get escalated permissions
permissions:
"id-token": "write"
"packages": "write"

announce:
needs:
- plan
- host
- publish-homebrew-formula
- custom-publish-homebrew
# use "always() && ..." to allow us to wait for all publish jobs while
# still allowing individual publish jobs to skip themselves (for prereleases).
# "host" however must run to completion, no skipping allowed!
if: ${{ always() && needs.host.result == 'success' && (needs.publish-homebrew-formula.result == 'skipped' || needs.publish-homebrew-formula.result == 'success') }}
if: ${{ always() && needs.host.result == 'success' && (needs.custom-publish-homebrew.result == 'skipped' || needs.custom-publish-homebrew.result == 'success') }}
runs-on: "ubuntu-22.04"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ rand = "0.8"
sha2 = "0.10"
tiny_http = "0.12"
tabled = { version = "0.20", features = ["ansi"] }
clap_complete = "4"
inquire = "0.9.4"
indicatif = "0.17"
nix = { version = "0.29", features = ["fs"] }
Expand Down
5 changes: 2 additions & 3 deletions dist-workspace.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,12 @@ ci = "github"
installers = ["shell", "homebrew"]
# Target platforms to build apps for (Rust target-triple syntax)
targets = ["aarch64-apple-darwin", "aarch64-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-unknown-linux-gnu"]
# A GitHub repo to push Homebrew formulas to
tap = "hotdata-dev/homebrew-tap"
# Customize the Homebrew formula name
formula = "cli"
# Path that installers should place binaries in
install-path = "~/.hotdata/cli"
# Publish jobs to run in CI
publish-jobs = ["homebrew"]
publish-jobs = ["./publish-homebrew"]
# Whether to install an updater program
install-updater = false

Expand Down
24 changes: 24 additions & 0 deletions src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,30 @@ pub enum Commands {
#[command(subcommand)]
command: Option<JobsCommands>,
},

/// Generate shell completions
Completions {
/// Shell to generate completions for
#[arg(value_enum)]
shell: ShellChoice,
},
}

#[derive(Clone, clap::ValueEnum)]
pub enum ShellChoice {
Bash,
Zsh,
Fish,
}

impl From<ShellChoice> for clap_complete::Shell {
fn from(s: ShellChoice) -> Self {
match s {
ShellChoice::Bash => clap_complete::Shell::Bash,
ShellChoice::Zsh => clap_complete::Shell::Zsh,
ShellChoice::Fish => clap_complete::Shell::Fish,
}
}
}

#[derive(Subcommand)]
Expand Down
7 changes: 7 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,13 @@ fn main() {
}
}
}
Commands::Completions { shell } => {
use clap::CommandFactory;
use clap_complete::generate;
let shell: clap_complete::Shell = shell.into();
let mut cmd = Cli::command();
generate(shell, &mut cmd, "hotdata", &mut std::io::stdout());
}
},
}
}
Expand Down
Loading