Skip to content

Commit e89db21

Browse files
committed
setup some actions
1 parent 85f6cf3 commit e89db21

File tree

4 files changed

+297
-0
lines changed

4 files changed

+297
-0
lines changed

.github/workflows/release.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: goreleaser
2+
3+
on:
4+
push:
5+
# run only against tags
6+
tags:
7+
- '*'
8+
9+
permissions:
10+
contents: write
11+
12+
jobs:
13+
goreleaser:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v3
17+
with:
18+
fetch-depth: 0
19+
- run: git fetch --force --tags
20+
- uses: actions/setup-go@v3
21+
with:
22+
go-version: 1.18
23+
cache: true
24+
- uses: goreleaser/goreleaser-action@v2
25+
with:
26+
distribution: goreleaser
27+
version: ${{ env.GITHUB_REF_NAME }}
28+
args: release --rm-dist
29+
env:
30+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.goreleaser.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
builds:
2+
- binary: aws-sso-util
3+
goos:
4+
- darwin
5+
- linux
6+
goarch:
7+
- amd64
8+
- arm64
9+
env:
10+
- CGO_ENABLED=0
11+
12+
release:
13+
prerelease: auto
14+
15+
universal_binaries:
16+
- replace: true
17+
18+
brews:
19+
- tap:
20+
owner: catpaladin
21+
name: aws-sso-util
22+
download_strategy: GitHubPrivateRepositoryReleaseDownloadStrategy
23+
custom_require: "lib/custom_download_strategy"
24+
commit_author:
25+
name: catpaladin
26+
27+
folder: HomebrewFormula
28+
29+
checksum:
30+
name_template: 'checksums.txt'
31+
Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
require "download_strategy"
2+
3+
# S3DownloadStrategy downloads tarballs from AWS S3.
4+
# To use it, add `:using => :s3` to the URL section of your
5+
# formula. This download strategy uses AWS access tokens (in the
6+
# environment variables `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`)
7+
# to sign the request. This strategy is good in a corporate setting,
8+
# because it lets you use a private S3 bucket as a repo for internal
9+
# distribution. (It will work for public buckets as well.)
10+
class S3DownloadStrategy < CurlDownloadStrategy
11+
def initialize(url, name, version, **meta)
12+
super
13+
end
14+
15+
def _fetch(url:, resolved_url:, timeout:)
16+
if url !~ %r{^https?://([^.].*)\.s3\.amazonaws\.com/(.+)$} &&
17+
url !~ %r{^s3://([^.].*?)/(.+)$}
18+
raise "Bad S3 URL: " + url
19+
end
20+
21+
bucket = Regexp.last_match(1)
22+
key = Regexp.last_match(2)
23+
24+
ENV["AWS_ACCESS_KEY_ID"] = ENV["HOMEBREW_AWS_ACCESS_KEY_ID"]
25+
ENV["AWS_SECRET_ACCESS_KEY"] = ENV["HOMEBREW_AWS_SECRET_ACCESS_KEY"]
26+
27+
begin
28+
signer = Aws::S3::Presigner.new
29+
s3url = signer.presigned_url :get_object, bucket: bucket, key: key
30+
rescue Aws::Sigv4::Errors::MissingCredentialsError
31+
ohai "AWS credentials missing, trying public URL instead."
32+
s3url = url
33+
end
34+
35+
curl_download s3url, to: temporary_path
36+
end
37+
end
38+
39+
# GitHubPrivateRepositoryDownloadStrategy downloads contents from GitHub
40+
# Private Repository. To use it, add
41+
# `:using => :github_private_repo` to the URL section of
42+
# your formula. This download strategy uses GitHub access tokens (in the
43+
# environment variables `HOMEBREW_GITHUB_API_TOKEN`) to sign the request. This
44+
# strategy is suitable for corporate use just like S3DownloadStrategy, because
45+
# it lets you use a private GitHub repository for internal distribution. It
46+
# works with public one, but in that case simply use CurlDownloadStrategy.
47+
class GitHubPrivateRepositoryDownloadStrategy < CurlDownloadStrategy
48+
require "utils/formatter"
49+
require "utils/github"
50+
51+
def initialize(url, name, version, **meta)
52+
super
53+
parse_url_pattern
54+
set_github_token
55+
end
56+
57+
def parse_url_pattern
58+
unless match = url.match(%r{https://github.com/([^/]+)/([^/]+)/(\S+)})
59+
raise CurlDownloadStrategyError, "Invalid url pattern for GitHub Repository."
60+
end
61+
62+
_, @owner, @repo, @filepath = *match
63+
end
64+
65+
def download_url
66+
"https://#{@github_token}@github.com/#{@owner}/#{@repo}/#{@filepath}"
67+
end
68+
69+
private
70+
71+
def _fetch(url:, resolved_url:, timeout:)
72+
curl_download download_url, to: temporary_path
73+
end
74+
75+
def set_github_token
76+
@github_token = ENV["HOMEBREW_GITHUB_API_TOKEN"]
77+
unless @github_token
78+
raise CurlDownloadStrategyError, "Environmental variable HOMEBREW_GITHUB_API_TOKEN is required."
79+
end
80+
81+
validate_github_repository_access!
82+
end
83+
84+
def validate_github_repository_access!
85+
# Test access to the repository
86+
GitHub.repository(@owner, @repo)
87+
rescue GitHub::HTTPNotFoundError
88+
# We only handle HTTPNotFoundError here,
89+
# becase AuthenticationFailedError is handled within util/github.
90+
message = <<~EOS
91+
HOMEBREW_GITHUB_API_TOKEN can not access the repository: #{@owner}/#{@repo}
92+
This token may not have permission to access the repository or the url of formula may be incorrect.
93+
EOS
94+
raise CurlDownloadStrategyError, message
95+
end
96+
end
97+
98+
# GitHubPrivateRepositoryReleaseDownloadStrategy downloads tarballs from GitHub
99+
# Release assets. To use it, add `:using => :github_private_release` to the URL section
100+
# of your formula. This download strategy uses GitHub access tokens (in the
101+
# environment variables HOMEBREW_GITHUB_API_TOKEN) to sign the request.
102+
class GitHubPrivateRepositoryReleaseDownloadStrategy < GitHubPrivateRepositoryDownloadStrategy
103+
def initialize(url, name, version, **meta)
104+
super
105+
end
106+
107+
def parse_url_pattern
108+
url_pattern = %r{https://github.com/([^/]+)/([^/]+)/releases/download/([^/]+)/(\S+)}
109+
unless @url =~ url_pattern
110+
raise CurlDownloadStrategyError, "Invalid url pattern for GitHub Release."
111+
end
112+
113+
_, @owner, @repo, @tag, @filename = *@url.match(url_pattern)
114+
end
115+
116+
def download_url
117+
"https://api.github.com/repos/#{@owner}/#{@repo}/releases/assets/#{asset_id}"
118+
end
119+
120+
private
121+
122+
def _fetch(url:, resolved_url:, timeout:)
123+
# HTTP request header `Accept: application/octet-stream` is required.
124+
# Without this, the GitHub API will respond with metadata, not binary.
125+
curl_download download_url, "--header", "Accept: application/octet-stream", "--header", "Authorization: token #{@github_token}", to: temporary_path
126+
end
127+
128+
def asset_id
129+
@asset_id ||= resolve_asset_id
130+
end
131+
132+
def resolve_asset_id
133+
release_metadata = fetch_release_metadata
134+
assets = release_metadata["assets"].select { |a| a["name"] == @filename }
135+
raise CurlDownloadStrategyError, "Asset file not found." if assets.empty?
136+
137+
assets.first["id"]
138+
end
139+
140+
def fetch_release_metadata
141+
release_url = "https://api.github.com/repos/#{@owner}/#{@repo}/releases/tags/#{@tag}"
142+
GitHub::API.open_rest(release_url)
143+
end
144+
end
145+
146+
# ScpDownloadStrategy downloads files using ssh via scp. To use it, add
147+
# `:using => :scp` to the URL section of your formula or
148+
# provide a URL starting with scp://. This strategy uses ssh credentials for
149+
# authentication. If a public/private keypair is configured, it will not
150+
# prompt for a password.
151+
#
152+
# @example
153+
# class Abc < Formula
154+
# url "scp://example.com/src/abc.1.0.tar.gz"
155+
# ...
156+
class ScpDownloadStrategy < AbstractFileDownloadStrategy
157+
def initialize(url, name, version, **meta)
158+
super
159+
parse_url_pattern
160+
end
161+
162+
def parse_url_pattern
163+
url_pattern = %r{scp://([^@]+@)?([^@:/]+)(:\d+)?/(\S+)}
164+
if @url !~ url_pattern
165+
raise ScpDownloadStrategyError, "Invalid URL for scp: #{@url}"
166+
end
167+
168+
_, @user, @host, @port, @path = *@url.match(url_pattern)
169+
end
170+
171+
def fetch
172+
ohai "Downloading #{@url}"
173+
174+
if cached_location.exist?
175+
puts "Already downloaded: #{cached_location}"
176+
else
177+
system_command! "scp", args: [scp_source, temporary_path.to_s]
178+
ignore_interrupts { temporary_path.rename(cached_location) }
179+
end
180+
end
181+
182+
def clear_cache
183+
super
184+
rm_rf(temporary_path)
185+
end
186+
187+
private
188+
189+
def scp_source
190+
path_prefix = "/" unless @path.start_with?("~")
191+
port_arg = "-P #{@port[1..-1]} " if @port
192+
"#{port_arg}#{@user}#{@host}:#{path_prefix}#{@path}"
193+
end
194+
end
195+
196+
class DownloadStrategyDetector
197+
class << self
198+
module Compat
199+
def detect(url, using = nil)
200+
strategy = super
201+
require_aws_sdk if strategy == S3DownloadStrategy
202+
strategy
203+
end
204+
205+
def detect_from_url(url)
206+
case url
207+
when %r{^s3://}
208+
S3DownloadStrategy
209+
when %r{^scp://}
210+
ScpDownloadStrategy
211+
else
212+
super(url)
213+
end
214+
end
215+
216+
def detect_from_symbol(symbol)
217+
case symbol
218+
when :github_private_repo
219+
GitHubPrivateRepositoryDownloadStrategy
220+
when :github_private_release
221+
GitHubPrivateRepositoryReleaseDownloadStrategy
222+
when :s3
223+
S3DownloadStrategy
224+
when :scp
225+
ScpDownloadStrategy
226+
else
227+
super(symbol)
228+
end
229+
end
230+
end
231+
232+
prepend Compat
233+
end
234+
end

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# aws-sso-util
2+

0 commit comments

Comments
 (0)