forked from hashicorp/terraform-provider-time
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
OpenTofu Core Development Team
committed
Dec 1, 2023
1 parent
00d68c5
commit fc3a67e
Showing
7 changed files
with
320 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
name: Trigger Artifact Release | ||
|
||
on: | ||
workflow_dispatch: | ||
|
||
permissions: | ||
contents: read | ||
actions: write | ||
|
||
jobs: | ||
trigger: | ||
uses: opentffoundation/scripts/.github/workflows/trigger.yml@main |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
name: Artifact Release | ||
|
||
on: | ||
workflow_dispatch: | ||
inputs: | ||
tag: | ||
description: "Release tag (v#.#.#)" | ||
type: string | ||
required: true | ||
|
||
permissions: | ||
contents: write | ||
|
||
jobs: | ||
release-dispatch: | ||
if: inputs.tag != '' | ||
uses: opentffoundation/scripts/.github/workflows/release.yml@main | ||
with: | ||
tag: ${{ inputs.tag }} | ||
secrets: | ||
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} | ||
GH_PAT: ${{ secrets.GH_PAT }} | ||
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} | ||
|
||
release-push: | ||
if: inputs.tag == '' | ||
uses: opentffoundation/scripts/.github/workflows/release.yml@main | ||
with: | ||
tag: ${{ github.ref_name }} | ||
secrets: | ||
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} | ||
GH_PAT: ${{ secrets.GH_PAT }} | ||
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
name: Sync Fork | ||
|
||
on: | ||
schedule: | ||
- cron: '15 */4 * * *' # every hour | ||
workflow_dispatch: # on button click | ||
|
||
jobs: | ||
sync: | ||
uses: opentffoundation/scripts/.github/workflows/sync.yml@main | ||
secrets: inherit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
module github.com/opentofu/scripts/go/sign | ||
|
||
go 1.21.1 | ||
|
||
require github.com/google/go-github/v54 v54.0.0 | ||
|
||
require ( | ||
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect | ||
github.com/cloudflare/circl v1.3.3 // indirect | ||
github.com/golang/protobuf v1.5.3 // indirect | ||
github.com/google/go-querystring v1.1.0 // indirect | ||
golang.org/x/crypto v0.12.0 // indirect | ||
golang.org/x/net v0.14.0 // indirect | ||
golang.org/x/oauth2 v0.11.0 // indirect | ||
golang.org/x/sys v0.11.0 // indirect | ||
google.golang.org/appengine v1.6.7 // indirect | ||
google.golang.org/protobuf v1.31.0 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA= | ||
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= | ||
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= | ||
github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= | ||
github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= | ||
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= | ||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= | ||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= | ||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= | ||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= | ||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= | ||
github.com/google/go-github/v54 v54.0.0 h1:OZdXwow4EAD5jEo5qg+dGFH2DpkyZvVsAehjvJuUL/c= | ||
github.com/google/go-github/v54 v54.0.0/go.mod h1:Sw1LXWHhXRZtzJ9LI5fyJg9wbQzYvFhW8W5P2yaAQ7s= | ||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= | ||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= | ||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= | ||
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= | ||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= | ||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= | ||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | ||
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= | ||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= | ||
golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU= | ||
golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk= | ||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= | ||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= | ||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= | ||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= | ||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= | ||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= | ||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= | ||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"flag" | ||
"fmt" | ||
"io" | ||
"log" | ||
"net/http" | ||
"os" | ||
"os/exec" | ||
"path/filepath" | ||
"strings" | ||
|
||
"github.com/google/go-github/v54/github" | ||
) | ||
|
||
var ( | ||
owner = flag.String("owner", "", "GitHub repo owner name") | ||
repo = flag.String("repo", "", "GitHub repo name") | ||
|
||
fingerprint = flag.String("fingerprint", "", "GPG fingerprint") | ||
) | ||
|
||
var c *github.Client | ||
|
||
func main() { | ||
flag.Parse() | ||
|
||
pat := os.Getenv("GITHUB_PAT") | ||
if pat == "" { | ||
panic("GITHUB_PAT environment variable not set") | ||
} | ||
|
||
c = github.NewTokenClient(nil, pat) | ||
|
||
err := resignReleases(context.Background(), *fingerprint) | ||
if err != nil { | ||
log.Fatalf("failed to resign releases: %v", err) | ||
} | ||
} | ||
|
||
func resignReleases(ctx context.Context, fingerprint string) error { | ||
tmpdir, err := os.MkdirTemp("", "") | ||
if err != nil { | ||
return err | ||
} | ||
defer os.RemoveAll(tmpdir) | ||
log.Printf("tmpdir: %s", tmpdir) | ||
|
||
releases, err := getReleases(ctx, "v") | ||
if err != nil { | ||
return fmt.Errorf("could not list %s/%s releases: %w", *owner, *repo, err) | ||
} | ||
log.Printf("releases: %d", len(releases)) | ||
|
||
for _, release := range releases { | ||
log.Printf("release: %s", release.GetTagName()) | ||
assets, _, err := c.Repositories.ListReleaseAssets(ctx, *owner, *repo, release.GetID(), &github.ListOptions{}) | ||
if err != nil { | ||
return fmt.Errorf("could not list %s/%s release %s assets: %w", *owner, *repo, release.GetTagName(), err) | ||
} | ||
log.Printf("assets: %d", len(assets)) | ||
var ( | ||
checksumAssetID int64 = -1 | ||
checksumAssetName string | ||
signatureAssetID int64 = -1 | ||
) | ||
for _, asset := range assets { | ||
log.Printf("asset: %s=%d", asset.GetName(), asset.GetID()) | ||
if strings.HasSuffix(asset.GetName(), "_SHA256SUMS") { | ||
checksumAssetID = asset.GetID() | ||
checksumAssetName = asset.GetName() | ||
} | ||
if strings.HasSuffix(asset.GetName(), "_SHA256SUMS.sig") { | ||
signatureAssetID = asset.GetID() | ||
} | ||
} | ||
log.Printf("checksum=%d,signature=%d", checksumAssetID, signatureAssetID) | ||
if checksumAssetID < 0 || signatureAssetID < 0 { | ||
return fmt.Errorf("could not find %s/%s release %s assets, checksum=%t,signature=%t", *owner, *repo, release.GetTagName(), checksumAssetID < 0, signatureAssetID < 0) | ||
} | ||
log.Printf("download asset %d as %s", checksumAssetID, checksumAssetName) | ||
if err := downloadAsset(ctx, checksumAssetID, filepath.Join(tmpdir, checksumAssetName)); err != nil { | ||
return fmt.Errorf("could not download %s/%s release %s checksum asset %d: %w", *owner, *repo, release.GetTagName(), checksumAssetID, err) | ||
} | ||
log.Printf("sign asset %s", checksumAssetName) | ||
signatureFilename, err := sign(fingerprint, tmpdir, checksumAssetName) | ||
if err != nil { | ||
return err | ||
} | ||
log.Printf("delete asset %d", signatureAssetID) | ||
if err := deleteAsset(ctx, signatureAssetID); err != nil { | ||
return fmt.Errorf("could not delete %s/%s release %s asset %d: %w", *owner, *repo, release.GetTagName(), signatureAssetID, err) | ||
} | ||
log.Printf("upload asset %s", signatureFilename) | ||
if err := uploadAsset(ctx, release.GetID(), filepath.Join(tmpdir, signatureFilename), signatureFilename); err != nil { | ||
return fmt.Errorf("could not upload %s/%s release %s asset %s: %w", *owner, *repo, release.GetTagName(), signatureFilename, err) | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func getReleases(ctx context.Context, prefix string) ([]*github.RepositoryRelease, error) { | ||
var repoReleases []*github.RepositoryRelease | ||
page := 1 | ||
for { | ||
releases, resp, err := c.Repositories.ListReleases(ctx, *owner, *repo, &github.ListOptions{ | ||
Page: page, | ||
PerPage: 99, | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if prefix != "" { | ||
for _, release := range releases { | ||
if strings.HasPrefix(release.GetTagName(), prefix) { | ||
repoReleases = append(repoReleases, release) | ||
} | ||
} | ||
} else { | ||
repoReleases = append(repoReleases, releases...) | ||
} | ||
if resp.NextPage == 0 { | ||
break | ||
} | ||
page = resp.NextPage | ||
} | ||
return repoReleases, nil | ||
} | ||
|
||
func downloadAsset(ctx context.Context, id int64, filename string) error { | ||
rc, _, err := c.Repositories.DownloadReleaseAsset(ctx, *owner, *repo, id, http.DefaultClient) | ||
if err != nil { | ||
return fmt.Errorf("could not download asset: %w", err) | ||
} | ||
defer rc.Close() | ||
f, err := os.Create(filename) | ||
if err != nil { | ||
return fmt.Errorf("could not create file %s: %w", filename, err) | ||
} | ||
defer f.Close() | ||
if _, err := io.Copy(f, rc); err != nil { | ||
return fmt.Errorf("could not copy asset data: %w", err) | ||
} | ||
if err := f.Close(); err != nil { | ||
return fmt.Errorf("could not close file %s: %w", filename, err) | ||
} | ||
return nil | ||
} | ||
|
||
func deleteAsset(ctx context.Context, id int64) error { | ||
_, err := c.Repositories.DeleteReleaseAsset(ctx, *owner, *repo, id) | ||
if err != nil { | ||
return fmt.Errorf("could not download asset: %w", err) | ||
} | ||
return nil | ||
} | ||
|
||
func uploadAsset(ctx context.Context, id int64, filename, name string) error { | ||
f, err := os.Open(filename) | ||
if err != nil { | ||
return fmt.Errorf("could not open %s: %w", filename, err) | ||
} | ||
defer f.Close() | ||
_, _, err = c.Repositories.UploadReleaseAsset(ctx, *owner, *repo, id, &github.UploadOptions{Name: name}, f) | ||
if err != nil { | ||
return fmt.Errorf("could not upload asset: %w", err) | ||
} | ||
return nil | ||
} | ||
|
||
func sign(fingerprint string, dir, filename string) (string, error) { | ||
signatureFilename := filename + ".sig" | ||
cmd := exec.Command("gpg", "--batch", "--local-user", fingerprint, "--output", signatureFilename, "--detach-sign", filename) | ||
cmd.Dir = dir | ||
b, err := cmd.CombinedOutput() | ||
if err != nil { | ||
return "", fmt.Errorf("command failed '%s': %w", string(b), err) | ||
} | ||
return signatureFilename, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
name: Artifacts Resign | ||
|
||
on: | ||
workflow_dispatch: | ||
|
||
permissions: | ||
contents: write | ||
|
||
jobs: | ||
resign: | ||
uses: opentffoundation/scripts/.github/workflows/sign.yml@main | ||
with: | ||
owner: ${{ github.repository_owner }} | ||
repo: ${{ github.event.repository.name }} | ||
secrets: | ||
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} | ||
GH_PAT: ${{ secrets.GH_PAT }} |