Skip to content

Commit

Permalink
feat: support updating actions (#663)
Browse files Browse the repository at this point in the history
* feat: support updating actions

* fix: add a update option and fix getLatestVersion

* docs: update document

* ci: test -update option

* docs: fix a link
  • Loading branch information
suzuki-shunsuke authored Dec 27, 2024
1 parent eede526 commit 175ef64
Show file tree
Hide file tree
Showing 12 changed files with 288 additions and 195 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/wc-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,6 @@ jobs:
env:
GITHUB_TOKEN: ${{github.token}}
- run: diff testdata/foo.yaml testdata/foo.yaml.after
- run: pinact run -u
env:
GITHUB_TOKEN: ${{github.token}}
2 changes: 0 additions & 2 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
linters:
enable-all: true
disable:
- execinquery # WARN The linter 'execinquery' is deprecated (since v1.58.0) due to: The repository of the linter has been archived by the owner.
- exportloopref # WARN The linter 'exportloopref' is deprecated (since v1.60.2) due to: Since Go1.22 (loopvar) this linter is no longer relevant. Replaced by copyloopvar.
- wsl
- gomnd
- err113
- lll
- godot
Expand Down
117 changes: 117 additions & 0 deletions INSTALL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Install

pinact is written in Go. So you only have to install a binary in your `PATH`.

There are some ways to install pinact.

1. [Homebrew](#homebrew)
1. [Scoop](#scoop)
1. [aqua](#aqua)
1. [GitHub Releases](#github-releases)
1. [Build an executable binary from source code yourself using Go](#build-an-executable-binary-from-source-code-yourself-using-go)

## Homebrew

You can install pinact using [Homebrew](https://brew.sh/).

```sh
brew install suzuki-shunsuke/pinact/pinact
```

## Scoop

You can install pinact using [Scoop](https://scoop.sh/).

```sh
scoop bucket add suzuki-shunsuke https://github.com/suzuki-shunsuke/scoop-bucket
scoop install pinact
```

## aqua

You can install pinact using [aqua](https://aquaproj.github.io/).

```sh
aqua g -i suzuki-shunsuke/pinact
```

## Build an executable binary from source code yourself using Go

```sh
go install github.com/suzuki-shunsuke/pinact/cmd/pinact@latest
```

## GitHub Releases

You can download an asset from [GitHub Releases](https://github.com/suzuki-shunsuke/pinact/releases).
Please unarchive it and install a pre built binary into `$PATH`.

### Verify downloaded assets from GitHub Releases

You can verify downloaded assets using some tools.

1. [GitHub CLI](https://cli.github.com/)
1. [slsa-verifier](https://github.com/slsa-framework/slsa-verifier)
1. [Cosign](https://github.com/sigstore/cosign)

### 1. GitHub CLI

You can install GitHub CLI by aqua.

```sh
aqua g -i cli/cli
```

```sh
version=v1.0.0
asset=pinact_darwin_arm64.tar.gz
gh release download -R suzuki-shunsuke/pinact "$version" -p "$asset"
gh attestation verify "$asset" \
-R suzuki-shunsuke/pinact \
--signer-workflow suzuki-shunsuke/go-release-workflow/.github/workflows/release.yaml
```

### 2. slsa-verifier

You can install slsa-verifier by aqua.

```sh
aqua g -i slsa-framework/slsa-verifier
```

```sh
version=v1.0.0
asset=pinact_darwin_arm64.tar.gz
gh release download -R suzuki-shunsuke/pinact "$version" -p "$asset" -p multiple.intoto.jsonl
slsa-verifier verify-artifact "$asset" \
--provenance-path multiple.intoto.jsonl \
--source-uri github.com/suzuki-shunsuke/pinact \
--source-tag "$version"
```

### 3. Cosign

You can install Cosign by aqua.

```sh
aqua g -i sigstore/cosign
```

```sh
version=v1.0.0
checksum_file="pinact_${version#v}_checksums.txt"
asset=pinact_darwin_arm64.tar.gz
gh release download "$version" \
-R suzuki-shunsuke/pinact \
-p "$asset" \
-p "$checksum_file" \
-p "${checksum_file}.pem" \
-p "${checksum_file}.sig"
cosign verify-blob \
--signature "${checksum_file}.sig" \
--certificate "${checksum_file}.pem" \
--certificate-identity-regexp 'https://github\.com/suzuki-shunsuke/go-release-workflow/\.github/workflows/release\.yaml@.*' \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
"$checksum_file"
cat "$checksum_file" | sha256sum -c --ignore-missing
```
150 changes: 12 additions & 138 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# pinact

[Motivation](#motivation) | [Install](#install) | [How to use](#how-to-use) | [GitHub Actions](https://github.com/suzuki-shunsuke/pinact-action) | [Configuration](#configuration) | [LICENSE](LICENSE)
[Motivation](#motivation) | [Install](INSTALL.md) | [How to use](#how-to-use) | [GitHub Actions](https://github.com/suzuki-shunsuke/pinact-action) | [Configuration](#configuration) | [LICENSE](LICENSE)

Pin GitHub Actions versions

Expand Down Expand Up @@ -40,7 +40,7 @@ index 84bd67a..5d92e44 100644
permissions:
```

[pinact also supports verifying version annotations](docs/codes/001.md).
pinact also supports [verifying version annotations](docs/codes/001.md) and [updating actions](#update-actions).

## Motivation

Expand Down Expand Up @@ -79,142 +79,6 @@ If you use linters such as [ghalint](https://github.com/suzuki-shunsuke/ghalint)
3. pinact is useful for non Renovate users
4. [pinact supports verifying version annotations](https://github.com/suzuki-shunsuke/pinact/blob/main/docs/codes/001.md)
## Install
pinact is written in Go. So you only have to install a binary in your `PATH`.

There are some ways to install pinact.

1. [Homebrew](#homebrew)
1. [aqua](#aqua)
1. [GitHub Releases](#github-releases)
1. [Build an executable binary from source code yourself using Go](#build)

### Homebrew

You can install pinact using [Homebrew](https://brew.sh/).

```console
$ brew install suzuki-shunsuke/pinact/pinact
```

### aqua

`aqua-registry >= v3.154.0`

You can install pinact using [aqua](https://aquaproj.github.io/).

```console
$ aqua g -i suzuki-shunsuke/pinact
```

### GitHub Releases

You can download an asset from [GitHub Reelases](https://github.com/suzuki-shunsuke/pinact/releases).
Please unarchive it and install a pre built binary into `$PATH`.

<details>
<summary>Verify downloaded assets from GitHub Releases</summary>

You can verify downloaded assets using some tools.

1. [GitHub CLI](https://cli.github.com/)
1. [slsa-verifier](https://github.com/slsa-framework/slsa-verifier)
1. [Cosign](https://github.com/sigstore/cosign)

#### 1. GitHub CLI

pinact >= v1.0.0

You can install GitHub CLI by aqua.

```sh
aqua g -i cli/cli
```

```sh
gh release download -R suzuki-shunsuke/pinact v1.0.0 -p pinact_darwin_arm64.tar.gz
gh attestation verify pinact_darwin_arm64.tar.gz \
-R suzuki-shunsuke/pinact \
--signer-workflow suzuki-shunsuke/go-release-workflow/.github/workflows/release.yaml
```

Output:

```
Loaded digest sha256:73d06ea7c7be9965c47863b2d9c04f298ae1d37edc18e162c540acb4ac030314 for file://pinact_darwin_arm64.tar.gz
Loaded 1 attestation from GitHub API
✓ Verification succeeded!
sha256:73d06ea7c7be9965c47863b2d9c04f298ae1d37edc18e162c540acb4ac030314 was attested by:
REPO PREDICATE_TYPE WORKFLOW
suzuki-shunsuke/go-release-workflow https://slsa.dev/provenance/v1 .github/workflows/release.yaml@7f97a226912ee2978126019b1e95311d7d15c97a
```

#### 2. slsa-verifier

You can install slsa-verifier by aqua.

```sh
aqua g -i slsa-framework/slsa-verifier
```

```sh
gh release download -R suzuki-shunsuke/pinact v1.0.0
slsa-verifier verify-artifact pinact_darwin_arm64.tar.gz \
--provenance-path multiple.intoto.jsonl \
--source-uri github.com/suzuki-shunsuke/pinact \
--source-tag v1.0.0
```

Output:

```
Verified signature against tlog entry index 136997022 at URL: https://rekor.sigstore.dev/api/v1/log/entries/108e9186e8c5677ae52579043db716d86ec00ccb03b2032503dc3a5a88d9e8b60c48c3d1cf62c5d1
Verified build using builder "https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@refs/tags/v2.0.0" at commit 664dfa3048ab7e48a581538740ea9698002703cd
Verifying artifact pinact_darwin_arm64.tar.gz: PASSED
PASSED: SLSA verification passed
```

#### 3. Cosign

You can install Cosign by aqua.

```sh
aqua g -i sigstore/cosign
```

```sh
gh release download -R suzuki-shunsuke/pinact v1.0.0
cosign verify-blob \
--signature pinact_1.0.0_checksums.txt.sig \
--certificate pinact_1.0.0_checksums.txt.pem \
--certificate-identity-regexp 'https://github\.com/suzuki-shunsuke/go-release-workflow/\.github/workflows/release\.yaml@.*' \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
pinact_1.0.0_checksums.txt
```

Output:

```
Verified OK
```

After verifying the checksum, verify the artifact.

```sh
cat pinact_1.0.0_checksums.txt | sha256sum -c --ignore-missing
```

</details>

### Build an executable binary from source code yourself using Go

```sh
go install github.com/suzuki-shunsuke/pinact/cmd/pinact@latest
```

## GitHub Access token
pinact calls GitHub REST API to get commit hashes and tags.
Expand Down Expand Up @@ -256,6 +120,16 @@ $ pinact init '.github/pinact.yaml'

About the configuration, please see [Configuration](#Configuration).

## Update actions

[#663](https://github.com/suzuki-shunsuke/pinact/pull/663) pinact >= v1.1.0

You can update actions using the `-update (-u)` option:

```sh
pinact run -u
```

## Verify version annotations

Please see [the document](docs/codes/001.md).
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.23.2
require (
github.com/google/go-cmp v0.6.0
github.com/google/go-github/v68 v68.0.0
github.com/hashicorp/go-version v1.7.0
github.com/mattn/go-colorable v0.1.13
github.com/sirupsen/logrus v1.9.3
github.com/spf13/afero v1.11.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ github.com/google/go-github/v68 v68.0.0 h1:ZW57zeNZiXTdQ16qrDiZ0k6XucrxZ2CGmoTvc
github.com/google/go-github/v68 v68.0.0/go.mod h1:K9HAUBovM2sLwM408A18h+wd9vqdLOEqTUCbnRIcx68=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=
github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ $ pinact init .github/pinact.yaml
}

func (r *Runner) initAction(c *cli.Context) error {
ctrl := run.New(c.Context)
ctrl := run.New(c.Context, &run.InputNew{})
log.SetLevel(c.String("log-level"), r.LogE)
configFilePath := c.Args().First()
if configFilePath == "" {
Expand Down
11 changes: 9 additions & 2 deletions pkg/cli/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,21 @@ $ pinact run .github/actions/foo/action.yaml .github/actions/bar/action.yaml
&cli.BoolFlag{
Name: "verify",
Aliases: []string{"v"},
Usage: "verify if pairs of commit SHA and version are correct",
Usage: "Verify if pairs of commit SHA and version are correct",
},
&cli.BoolFlag{
Name: "update",
Aliases: []string{"u"},
Usage: "Update actions to latest versions",
},
},
}
}

func (r *Runner) runAction(c *cli.Context) error {
ctrl := run.New(c.Context)
ctrl := run.New(c.Context, &run.InputNew{
Update: c.Bool("update"),
})
log.SetLevel(c.String("log-level"), r.LogE)
pwd, err := os.Getwd()
if err != nil {
Expand Down
10 changes: 8 additions & 2 deletions pkg/controller/run/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,23 @@ import (
type Controller struct {
repositoriesService RepositoriesService
fs afero.Fs
update bool
}

func New(ctx context.Context) *Controller {
type InputNew struct {
Update bool
}

func New(ctx context.Context, input *InputNew) *Controller {
gh := github.New(ctx)
return &Controller{
repositoriesService: &RepositoriesServiceImpl{
tags: map[string]*ListTagsResult{},
commits: map[string]*GetCommitSHA1Result{},
RepositoriesService: gh.Repositories,
},
fs: afero.NewOsFs(),
fs: afero.NewOsFs(),
update: input.Update,
}
}

Expand Down
Loading

0 comments on commit 175ef64

Please sign in to comment.