From 13ed1b5bb1446a8a5eefbb0641c9277a2f7a9127 Mon Sep 17 00:00:00 2001 From: galargh Date: Mon, 8 Jul 2024 10:38:12 +1000 Subject: [PATCH] feat: ci: automate the new release process --- .github/workflows/docker.yml | 28 +-- .github/workflows/release.yml | 227 +++++++++++++------ .gitignore | 3 + .goreleaser.yaml | 50 ++-- cmd/release/README.md | 42 ++++ cmd/release/main.go | 135 +++++++++++ documentation/misc/RELEASE_ISSUE_TEMPLATE.md | 44 ++-- go.mod | 4 +- scripts/publish-checksums.sh | 39 +--- scripts/version-check.sh | 39 ---- 10 files changed, 403 insertions(+), 208 deletions(-) create mode 100644 cmd/release/README.md create mode 100644 cmd/release/main.go delete mode 100755 scripts/version-check.sh diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index cfde8bb42e1..6df6d0e4a4b 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -4,16 +4,21 @@ on: push: branches: - master - - release/* tags: - v* + pull_request: + branches: + - master + - release/v* + - releases schedule: - cron: '0 0 * * *' workflow_dispatch: inputs: - ref: - description: The GitHub ref (e.g. refs/tags/v1.0.0) to release + publish: + description: 'Publish the Docker image' required: false + default: 'false' defaults: run: @@ -24,7 +29,7 @@ permissions: jobs: docker: - name: Docker (${{ matrix.image }} / ${{ matrix.network }}) [publish=${{ (inputs.ref || github.ref) == 'refs/heads/master' || startsWith(inputs.ref || github.ref, 'refs/tags/') }}] + name: Docker (${{ matrix.image }} / ${{ matrix.network }}) [publish=${{ inputs.publish == 'true' || github.event_name != 'pull_request' }}] runs-on: ubuntu-latest strategy: fail-fast: false @@ -40,13 +45,13 @@ jobs: - image: lotus network: mainnet env: - PUBLISH: ${{ github.ref == 'refs/heads/master' || startsWith(inputs.ref || github.ref, 'refs/tags/') }} + PUBLISH: ${{ inputs.publish == 'true' || github.event_name != 'pull_request' }} steps: - id: channel env: - IS_MASTER: ${{ (inputs.ref || github.ref) == 'refs/heads/master' }} - IS_TAG: ${{ startsWith(inputs.ref || github.ref, 'refs/tags/') }} - IS_RC: ${{ contains(inputs.ref || github.ref, '-rc') }} + IS_MASTER: ${{ github.ref == 'refs/heads/master' }} + IS_TAG: ${{ startsWith(github.ref, 'refs/tags/') }} + IS_RC: ${{ contains(github.ref, '-rc') }} IS_SCHEDULED: ${{ github.event_name == 'schedule' }} run: | channel='' @@ -67,12 +72,9 @@ jobs: - uses: actions/checkout@v4 with: submodules: 'recursive' - ref: ${{ inputs.ref || github.ref }} - id: git - env: - REF: ${{ inputs.ref || github.ref }} run: | - ref="${REF#refs/heads/}" + ref="${GITHUB_REF#refs/heads/}" ref="${ref#refs/tags/}" sha="$(git rev-parse --short HEAD)" echo "ref=$ref" | tee -a "$GITHUB_OUTPUT" @@ -86,7 +88,7 @@ jobs: images: filecoin/${{ matrix.image }} tags: | type=raw,enable=${{ steps.channel.outputs.channel != '' }},value=${{ steps.channel.outputs.channel }} - type=raw,enable=${{ startsWith(inputs.ref || github.ref, 'refs/tags/') }},value=${{ steps.git.outputs.ref }} + type=raw,enable=${{ startsWith(github.ref, 'refs/tags/') }},value=${{ steps.git.outputs.ref }} type=raw,value=${{ steps.git.outputs.sha }} flavor: | latest=false diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 12ea6e3f90e..9777542e0c8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,16 +3,30 @@ name: Release on: push: branches: - - ci/* - - release/* - tags: - - v* + - release/v* + - releases + paths: + - build/version.go + pull_request: + branches: + - release/v* + - releases + paths: + - build/version.go workflow_dispatch: inputs: - ref: - description: The GitHub ref (e.g. refs/tags/v1.0.0) to release + publish: + description: 'Publish the release' required: false - + default: 'false' + draft: + description: 'Create a draft release' + required: false + default: 'true' + target_commitish: + description: 'The commitish value that determines where the Git tag is created from' + required: false + default: '' defaults: run: shell: bash @@ -21,121 +35,184 @@ permissions: contents: read jobs: + check: + name: Check which projects need to be built + runs-on: ubuntu-latest + outputs: + projects: ${{ steps.projects.outputs.projects }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - id: projects + env: + TARGET_REF: ${{ github.base_ref || github.ref }} + run: | + go run cmd/release/main.go --json list-projects | jq -r '.msg' | + jq 'map(select(.version | endswith("-dev") | not))' | + jq 'map(select(.released | not))' | + jq 'map(select(.prerelease != ((env.TARGET_REF | sub("^refs/heads/"; "")) == "releases")))' | + jq -c '.' | xargs -I {} -0 echo "projects={}" | + tee -a $GITHUB_OUTPUT build: - name: Build (${{ matrix.os }}/${{ matrix.arch }}) + needs: [check] + if: needs.check.outputs.projects != '[]' + name: Build ${{ matrix.project }} (${{ matrix.runner }}) runs-on: ${{ matrix.runner }} strategy: fail-fast: false matrix: - include: - - runner: ubuntu-latest - os: Linux - arch: X64 - - runner: macos-13 - os: macOS - arch: X64 - - runner: macos-14 - os: macOS - arch: ARM64 + project: ${{ fromJSON(needs.check.outputs.projects).*.name }} + runner: + - ubuntu-latest # Linux X64 + - macos-13 # MacOs X64 + - macos-14 # MacOS ARM64 steps: - - env: - OS: ${{ matrix.os }} - ARCH: ${{ matrix.arch }} + - run: echo "Building on $RUNNER_OS/$RUNNER_ARCH" + - id: project + env: + projects: ${{ needs.check.outputs.projects }} + name: ${{ matrix.project }} run: | - if [[ "$OS" != "$RUNNER_OS" || "$ARCH" != "$RUNNER_ARCH" ]]; then - echo "::error title=Unexpected Runner::Expected $OS/$ARCH, got $RUNNER_OS/$RUNNER_ARCH" - exit 1 - fi - - uses: actions/checkout@v4 - with: - path: actions + jq -nc 'env.projects | fromjson | map(select(.name == env.name)) | .[0]' | + xargs -I {} -0 echo "config={}" | + tee -a $GITHUB_OUTPUT - uses: actions/checkout@v4 with: submodules: 'recursive' - ref: ${{ inputs.ref || github.ref }} - path: lotus - - uses: ./actions/.github/actions/install-system-dependencies - - uses: ./actions/.github/actions/install-go - with: - working-directory: lotus + - uses: ./.github/actions/install-system-dependencies + - uses: ./.github/actions/install-go - env: GITHUB_TOKEN: ${{ github.token }} - run: make deps lotus lotus-miner lotus-worker - working-directory: lotus + run: make deps + - if: matrix.project == 'node' + env: + GITHUB_TOKEN: ${{ github.token }} + run: make lotus + - if: matrix.project == 'miner' + env: + GITHUB_TOKEN: ${{ github.token }} + run: make lotus-miner lotus-worker - if: runner.os == 'macOS' - run: otool -hv lotus - working-directory: lotus + run: if [[ -f lotus ]]; then otool -hv lotus; fi - env: - INPUTS_REF: ${{ inputs.ref }} + LOTUS_VERSION_IGNORE_COMMIT: 1 + expected: ${{ fromJSON(steps.project.outputs.config).version }} run: | - export GITHUB_REF=${INPUTS_REF:-$GITHUB_REF} - ../actions/scripts/version-check.sh ./lotus - working-directory: lotus + for bin in lotus lotus-miner lotus-worker; do + if [[ -f ./$bin ]]; then + chmod +x ./$bin + actual=$(./$bin --version | cut -d' ' -f3) + if [[ "$actual" != "$expected" ]]; then + echo "::error title=Version Mismatch::Expected $expected, got $actual (./$bin)" + exit 1 + fi + fi + done - uses: actions/upload-artifact@v4 with: - name: lotus-${{ matrix.os }}-${{ matrix.arch }} + name: lotus-${{ matrix.project }}-${{ runner.os }}-${{ runner.arch }} path: | - lotus/lotus - lotus/lotus-miner - lotus/lotus-worker + lotus + lotus-miner + lotus-worker release: - name: Release [publish=${{ startsWith(inputs.ref || github.ref, 'refs/tags/') }}] + needs: [check, build] + if: needs.check.outputs.projects != '[]' + name: Release ${{ matrix.project }} [publish=${{ inputs.publish == 'true' || github.event_name != 'pull_request' }}] permissions: # This enables the job to create and/or update GitHub releases contents: write runs-on: ubuntu-latest - needs: [build] + strategy: + fail-fast: false + matrix: + project: ${{ fromJSON(needs.check.outputs.projects).*.name }} env: - PUBLISH: ${{ startsWith(inputs.ref || github.ref, 'refs/tags/') }} + PUBLISH: ${{ inputs.publish == 'true' || github.event_name != 'pull_request' }} + IS_DRAFT: ${{ inputs.draft == 'true' || github.event_name == 'pull_request' }} steps: - - uses: actions/checkout@v4 - with: - path: actions + - id: project + env: + projects: ${{ needs.check.outputs.projects }} + name: ${{ matrix.project }} + run: | + jq -nc 'env.projects | fromjson | map(select(.name == env.name)) | .[0]' | + xargs -I {} -0 echo "config={}" | + tee -a $GITHUB_OUTPUT - uses: actions/checkout@v4 with: submodules: 'recursive' fetch-depth: 0 - path: lotus - ref: ${{ inputs.ref || github.ref }} - uses: actions/download-artifact@v4 with: - name: lotus-Linux-X64 + name: lotus-${{ matrix.project }}-Linux-X64 path: linux_amd64_v1 - uses: actions/download-artifact@v4 with: - name: lotus-macOS-X64 + name: lotus-${{ matrix.project }}-macOS-X64 path: darwin_amd64_v1 - uses: actions/download-artifact@v4 with: - name: lotus-macOS-ARM64 + name: lotus-${{ matrix.project }}-macOS-ARM64 path: darwin_arm64 - - uses: ./actions/.github/actions/install-go - with: - working-directory: lotus + - uses: ./.github/actions/install-go - uses: ipfs/download-ipfs-distribution-action@v1 with: name: kubo version: v0.16.0 + cache: false + - name: Install yq + env: + GITHUB_TOKEN: ${{ github.token }} + run: | + gh release --repo mikefarah/yq download v4.44.2 -p yq_linux_amd64 + sudo mv yq_linux_amd64 /usr/bin/yq + sudo chmod +x /usr/bin/yq + - if: env.IS_DRAFT == 'false' + run: yq -i '.release.draft = false' '.goreleaser.yaml' + - if: env.PUBLISH == 'true' && env.IS_DRAFT == 'false' && fromJSON(steps.project.outputs.config).latest && !fromJSON(steps.project.outputs.config).prerelease + run: yq -i '.brews.[0].skip_upload = false' '.goreleaser.yaml' + - if: matrix.project == 'node' + env: + BREW_INSTALL: | + bin.install "lotus" + BREW_TEST: | + system "#{bin}/lotus --version" + run: | + yq -i '(.builds[] | select(.id == "lotus")).skip = false' '.goreleaser.yaml' + yq -i '.brews[0].install = strenv(BREW_INSTALL)' '.goreleaser.yaml' + yq -i '.brews[0].test = strenv(BREW_TEST)' '.goreleaser.yaml' + - if: matrix.project == 'miner' + env: + BREW_INSTALL: | + bin.install "lotus-miner" + bin.install "lotus-worker" + BREW_TEST: | + system "#{bin}/lotus-miner --version" + system "#{bin}/lotus-worker --version" + run: | + yq -i '(.builds[] | select(.id == "lotus-miner" or .id == "lotus-worker")).skip = false' '.goreleaser.yaml' + yq -i '.brews[0].install = strenv(BREW_INSTALL)' '.goreleaser.yaml' + yq -i '.brews[0].test = strenv(BREW_TEST)' '.goreleaser.yaml' - uses: goreleaser/goreleaser-action@7ec5c2b0c6cdda6e8bbb49444bc797dd33d74dd8 # v5.0.0 with: distribution: goreleaser-pro version: 2.0.1 - args: release --clean ${{ env.PUBLISH == 'false' && '--snapshot' || '' }} - workdir: lotus + args: release --clean --skip=validate ${{ env.PUBLISH == 'false' && '--snapshot' || '' }} env: - GITHUB_TOKEN: ${{ env.PUBLISH == 'true' && secrets.GORELEASER_GITUB_TOKEN || github.token || '' }} + PROJECT_NAME: ${{ matrix.project == 'node' && 'lotus' || format('lotus-{0}', matrix.project) }} + GITHUB_TOKEN: ${{ env.PUBLISH == 'true' && (secrets.GORELEASER_GITHUB_TOKEN || github.token) || '' }} GORELEASER_KEY: ${{ env.PUBLISH == 'true' && secrets.GORELEASER_KEY || '' }} - - env: - INPUTS_REF: ${{ inputs.ref }} - run: | - export GITHUB_REF=${INPUTS_REF:-$GITHUB_REF} - ../actions/scripts/generate-checksums.sh - working-directory: lotus - - if: env.PUBLISH == 'true' + TAG: ${{ fromJSON(steps.project.outputs.config).tag }} + VERSION: ${{ fromJSON(steps.project.outputs.config).version }} + IS_LATEST: ${{ fromJSON(steps.project.outputs.config).latest }} + IS_PRERELEASE: ${{ fromJSON(steps.project.outputs.config).prerelease }} + TARGET_COMMITISH: ${{ inputs.target_commitish || (github.event_name == 'pull_request' && github.event.pull_request.base.ref || github.sha) }} + HEADER: '' + - run: ./scripts/generate-checksums.sh + - if: env.PUBLISH == 'true' && env.IS_DRAFT == 'false' env: GITHUB_TOKEN: ${{ github.token }} - INPUTS_REF: ${{ inputs.ref }} - run: | - export GITHUB_REF=${INPUTS_REF:-$GITHUB_REF} - ../actions/scripts/publish-checksums.sh - working-directory: lotus + TAG: ${{ fromJSON(steps.project.outputs.config).tag }} + run: ./scripts/publish-checksums.sh diff --git a/.gitignore b/.gitignore index a40ab0bd573..142d8f27ce2 100644 --- a/.gitignore +++ b/.gitignore @@ -53,6 +53,9 @@ build/builtin-actors/v* build/builtin-actors/*.car dist/ +darwin_amd64_v1/ +darwin_arm64/ +linux_amd64_v1/ # The following files are checked into git and result diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 7b94168c612..138f37a5f3e 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -1,9 +1,7 @@ # yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json version: 2 - -project_name: lotus - +project_name: "{{ .Env.PROJECT_NAME }}" universal_binaries: - id: lotus replace: true @@ -14,7 +12,6 @@ universal_binaries: - id: lotus-worker replace: true name_template: lotus-worker - builds: - id: lotus binary: lotus @@ -31,7 +28,8 @@ builds: - goos: linux goarch: arm64 prebuilt: - path: '{{ .Env.GITHUB_WORKSPACE }}/{{ .Os }}_{{ .Arch }}{{ with .Amd64 }}_{{ . }}{{ end }}/lotus' + path: "{{ .Env.GITHUB_WORKSPACE }}/{{ .Os }}_{{ .Arch }}{{ with .Amd64 }}_{{ . }}{{ end }}/lotus" + skip: true - id: lotus-miner binary: lotus-miner builder: prebuilt @@ -47,7 +45,8 @@ builds: - goos: linux goarch: arm64 prebuilt: - path: '{{ .Env.GITHUB_WORKSPACE }}/{{ .Os }}_{{ .Arch }}{{ with .Amd64 }}_{{ . }}{{ end }}/lotus-miner' + path: "{{ .Env.GITHUB_WORKSPACE }}/{{ .Os }}_{{ .Arch }}{{ with .Amd64 }}_{{ . }}{{ end }}/lotus-miner" + skip: true - id: lotus-worker binary: lotus-worker builder: prebuilt @@ -63,51 +62,50 @@ builds: - goos: linux goarch: arm64 prebuilt: - path: '{{ .Env.GITHUB_WORKSPACE }}/{{ .Os }}_{{ .Arch }}{{ with .Amd64 }}_{{ . }}{{ end }}/lotus-worker' - + path: "{{ .Env.GITHUB_WORKSPACE }}/{{ .Os }}_{{ .Arch }}{{ with .Amd64 }}_{{ . }}{{ end }}/lotus-worker" + skip: true archives: - id: primary format: tar.gz wrap_in_directory: true - name_template: "{{ .ProjectName }}_v{{ .Version }}_{{ .Os }}_{{ .Arch }}" + name_template: "{{ .Env.PROJECT_NAME }}_v{{ .Env.VERSION }}_{{ .Os }}_{{ .Arch }}" files: # this is a dumb but required hack so it doesn't include the default files # https://github.com/goreleaser/goreleaser/issues/602 - _n_o_n_e_* - release: github: owner: filecoin-project name: lotus - prerelease: auto - name_template: "v{{.Version}}" - + draft: true + header: "{{ .Env.HEADER }}" + make_latest: "{{ .Env.IS_LATEST }}" + name_template: "{{ .Env.TAG }}" + prerelease: "{{ .Env.IS_PRERELEASE }}" + replace_existing_artifacts: true + replace_existing_draft: false + tag: "{{ .Env.TAG }}" + target_commitish: "{{ .Env.TARGET_COMMITISH }}" brews: - - repository: + - name: "{{ .Env.PROJECT_NAME }}" + repository: owner: filecoin-project name: homebrew-lotus branch: master ids: - primary - install: | - bin.install "lotus" - bin.install "lotus-miner" - bin.install "lotus-worker" - test: | - system "#{bin}/lotus --version" - system "#{bin}/lotus-miner --version" - system "#{bin}/lotus-worker --version" + install: "" + test: "" directory: Formula homepage: "https://filecoin.io" description: "A homebrew cask for installing filecoin-project/lotus on MacOS" license: MIT - skip_upload: auto + skip_upload: true dependencies: - name: hwloc - + commit_msg_template: "Brew formula update for {{ .Env.PROJECT_NAME }} version {{ .Env.TAG }}" # produced manually so we can include cid checksums checksum: disable: true - snapshot: - name_template: "{{ .Version }}" + name_template: "{{ .Env.PROJECT_NAME }}_v{{ .Env.VERSION }}" diff --git a/cmd/release/README.md b/cmd/release/README.md new file mode 100644 index 00000000000..92b55507608 --- /dev/null +++ b/cmd/release/README.md @@ -0,0 +1,42 @@ +# Lotus Release Tool + +The Lotus Release Tool is a CLI (Command Line Interface) utility designed to facilitate interactions with the Lotus Node and Miner metadata. This tool allows users to retrieve version information in either JSON or text format. The Lotus Release Tool was developed as a part of the [2024Q2 release process automation initiative](https://github.com/filecoin-project/lotus/issues/12010) and is used in the GitHub Actions workflows related to the release process. + +## Features + +- List all projects with their expected version information. +- Output logs in JSON or text format. + +## Installation + +To install the Lotus Release Tool, you need to have Go installed on your system. + +1. Build the tool: + ```sh + go build -o release ./cmd/release + ``` + +## Usage + +The `release` tool provides several commands and options to interact with the Lotus Node and Miner. + +### Commands + +- **List Projects**: List all projects with their version information. + ```sh + ./release list-projects + ``` + +### Options + +- **--json**: Format output as JSON. + ```sh + ./release --json list-projects + ``` + +## Example + +List Lotus Node and Lotus Miner version information with JSON formatted output: +```sh +./release --json list-projects +``` diff --git a/cmd/release/main.go b/cmd/release/main.go new file mode 100644 index 00000000000..711ab1356b2 --- /dev/null +++ b/cmd/release/main.go @@ -0,0 +1,135 @@ +package main + +import ( + "encoding/json" + "os" + "os/exec" + "strings" + + log "github.com/sirupsen/logrus" + "github.com/urfave/cli/v2" + "golang.org/x/mod/semver" + + "github.com/filecoin-project/lotus/build" +) + +var _tags []string + +func getTags() []string { + if _tags == nil { + output, err := exec.Command("git", "tag").Output() + if err != nil { + log.Fatal(err) + } + _tags = strings.Split(string(output), "\n") + } + return _tags +} + +func isPrerelease(version string) bool { + return semver.Prerelease("v"+version) != "" +} + +func isLatest(name, version string) bool { + if isPrerelease(version) { + return false + } + prefix := getPrefix(name) + tags := getTags() + for _, t := range tags { + if strings.HasPrefix(t, prefix) { + v := strings.TrimPrefix(t, prefix) + if !isPrerelease(v) { + if semver.Compare("v"+v, "v"+version) > 0 { + return false + } + } + } + } + return true +} + +func isReleased(tag string) bool { + tags := getTags() + for _, t := range tags { + if t == tag { + return true + } + } + return false +} + +func getPrefix(name string) string { + if name == "node" { + return "v" + } + return name + "/v" +} + +type project struct { + Name string `json:"name"` + Version string `json:"version"` + Tag string `json:"tag"` + Latest bool `json:"latest"` + Prerelease bool `json:"prerelease"` + Released bool `json:"released"` +} + +func getProject(name, version string) project { + tag := getPrefix(name) + version + return project{ + Name: name, + Version: version, + Tag: getPrefix(name) + version, + Latest: isLatest(name, version), + Prerelease: isPrerelease(version), + Released: isReleased(tag), + } +} + +func main() { + app := &cli.App{ + Name: "release", + Usage: "Lotus release tool", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "json", + Usage: "Format output as JSON", + }, + }, + Before: func(c *cli.Context) error { + if c.Bool("json") { + log.SetFormatter(&log.JSONFormatter{}) + } else { + log.SetFormatter(&log.TextFormatter{ + TimestampFormat: "2006-01-02 15:04:05", + FullTimestamp: true, + }) + } + log.SetOutput(os.Stdout) + return nil + }, + Commands: []*cli.Command{ + { + Name: "list-projects", + Usage: "List all projects", + Action: func(c *cli.Context) error { + projects := []project{ + getProject("node", build.NodeBuildVersion), + getProject("miner", build.MinerBuildVersion), + } + b, err := json.MarshalIndent(projects, "", " ") + if err != nil { + log.Fatal(err) + } + log.Info(string(b)) + return nil + }, + }, + }, + } + + if err := app.Run(os.Args); err != nil { + log.Fatal(err) + } +} diff --git a/documentation/misc/RELEASE_ISSUE_TEMPLATE.md b/documentation/misc/RELEASE_ISSUE_TEMPLATE.md index e26e06b326d..b35c26027b8 100644 --- a/documentation/misc/RELEASE_ISSUE_TEMPLATE.md +++ b/documentation/misc/RELEASE_ISSUE_TEMPLATE.md @@ -18,32 +18,40 @@ **Prepping an RC**: -- [ ] version string in `build/version.go` needs to be updated to end with '-rcX' (in the `release/vX.Y.Z` branch) -- [ ] run `make gen && make docsgen-cli` -- [ ] Generate changelog using the script at scripts/mkreleaselog -- [ ] Add contents of generated text to lotus/CHANGELOG.md in addition to other details -- [ ] Commit using PR -- [ ] tag commit with `vX.Y.Z-rcN` -- [ ] cut a pre-release [here](https://github.com/filecoin-project/lotus/releases/new?prerelease=true) +Perform the following changes to the `release/vX.Y.Z` branch through a PR: +- [ ] update the version string in `build/version.go` to one ending with '-rcX' +- [ ] run `make gen && make docsgen-cli` to generate documentation +- [ ] run `scripts/mkreleaselog` to generate changelog + - [ ] add the contents of generated changelog to `CHANGELOG.md` + - [ ] add any other details about the release to `CHANGELOG.md` +- [ ] create a **PR** targetting `release/vX.Y.Z` branch + - Opening a PR will trigger a CI run that will build the release and run goreleaser in a dry/snapshot mode + - Merging the PR will trigger a CI run that will publish the release to GitHub (including the creation of a GitHub release and a tag) +- [ ] find the newly created [GitHub release](https://github.com/filecoin-project/lotus/releases) and update its' description accordingly **Testing** Test the release candidate thoroughly, including automated and manual tests to ensure stability and functionality across various environments and scenarios. **Stable Release** - - [ ] Final preparation - - [ ] Verify that version string in [`version.go`](https://github.com/filecoin-project/lotus/blob/master/build/version.go) has been updated. - - [ ] Verify that codegen is up to date (`make gen && make docsgen-cli`) - - [ ] Ensure that [CHANGELOG.md](https://github.com/filecoin-project/lotus/blob/master/CHANGELOG.md) is up to date - - [ ] Open a pull request against the `releases` branch with a merge of `release-vX.Y.Z`. - - [ ] Cut the release [here](https://github.com/filecoin-project/lotus/releases/new?prerelease=false&target=releases). - - The target should be the `releases` branch. - - Either make the tag locally and push to the `releases` branch, or allow GitHub to create a new tag via the UI when the release is published. + +Perform the following changes to the `release/vX.Y.Z` branch (optionally, through a PR): +- [ ] update the version string in `build/version.go` to one **NOT** ending with '-rcX' +- [ ] run `make gen && make docsgen-cli` to generate documentation +- [ ] ensure `CHANGELOG.md` is up to date (run `scripts/mkreleaselog` and update `CHANGELOG.md` if needed) +- [ ] either commit the changes directly or open a PR against the `release/vX.Y.Z` branch + +Perform the following changes to the `releases` branch through a PR: +- [ ] create a **PR** targetting `releases` branch (base) from `release/vX.Y.Z` branch (head) + - Opening a PR will trigger a CI run that will build the release and run goreleaser in a dry/snapshot mode + - Merging the PR will trigger a CI run that will publish the release to GitHub (including the creation of a GitHub release and a tag) +- [ ] find the newly created [GitHub release](https://github.com/filecoin-project/lotus/releases) and update its' description accordingly **Post-Release** - - [ ] Open a pull request against the `master` branch with a merge of the `releases` branch. Conflict resolution should ignore the changes to `version.go` (keep the `-dev` version from master). Do NOT delete the `releases` branch when doing so! - - [ ] Update [RELEASE_ISSUE_TEMPLATE.md](https://github.com/filecoin-project/lotus/blob/master/documentation/misc/RELEASE_ISSUE_TEMPLATE.md) with any improvements determined from this latest release iteration. - - [ ] Create an issue using [RELEASE_ISSUE_TEMPLATE.md](https://github.com/filecoin-project/lotus/blob/master/documentation/misc/RELEASE_ISSUE_TEMPLATE.md) for the _next_ release. + +- [ ] Open a pull request against the `master` branch with a merge of the `releases` branch. Conflict resolution should ignore the changes to `version.go` (keep the `-dev` version from master). Do NOT delete the `releases` branch when doing so! +- [ ] Update [RELEASE_ISSUE_TEMPLATE.md](https://github.com/filecoin-project/lotus/blob/master/documentation/misc/RELEASE_ISSUE_TEMPLATE.md) with any improvements determined from this latest release iteration. +- [ ] Create an issue using [RELEASE_ISSUE_TEMPLATE.md](https://github.com/filecoin-project/lotus/blob/master/documentation/misc/RELEASE_ISSUE_TEMPLATE.md) for the _next_ release. ## ❤️ Contributors diff --git a/go.mod b/go.mod index 76d5bb8c478..b4f7d335247 100644 --- a/go.mod +++ b/go.mod @@ -123,6 +123,7 @@ require ( github.com/raulk/clock v1.1.0 github.com/raulk/go-watchdog v1.3.0 github.com/samber/lo v1.39.0 + github.com/sirupsen/logrus v1.9.2 github.com/stretchr/testify v1.9.0 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/triplewz/poseidon v0.0.0-20230828015038-79d8165c88ed @@ -145,6 +146,7 @@ require ( go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.23.0 + golang.org/x/mod v0.17.0 golang.org/x/net v0.25.0 golang.org/x/sync v0.7.0 golang.org/x/sys v0.20.0 @@ -296,7 +298,6 @@ require ( github.com/rivo/uniseg v0.4.7 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shirou/gopsutil v2.18.12+incompatible // indirect - github.com/sirupsen/logrus v1.9.2 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/tidwall/gjson v1.14.4 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect @@ -317,7 +318,6 @@ require ( go.uber.org/mock v0.4.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect - golang.org/x/mod v0.17.0 // indirect golang.org/x/text v0.15.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 // indirect diff --git a/scripts/publish-checksums.sh b/scripts/publish-checksums.sh index ff80f388bdc..1dc2e41de84 100755 --- a/scripts/publish-checksums.sh +++ b/scripts/publish-checksums.sh @@ -9,8 +9,8 @@ if [ -z "${GITHUB_TOKEN}" ]; then exit 1 fi -if [[ "$GITHUB_REF" != refs/tags/* ]]; then - echo "$GITHUB_REF is not a tag, publish failed" +if [ -z "${TAG}" ]; then + echo "\${TAG} not set, publish failed" exit 1 fi @@ -23,48 +23,17 @@ do command -v "${REQUIRE}" >/dev/null 2>&1 || echo >&2 "'${REQUIRE}' must be installed" done -GITHUB_TAG="${GITHUB_REF#refs/tags/}" - #see if the release already exists by tag RELEASE_RESPONSE=` curl \ --fail \ --header "Authorization: token ${GITHUB_TOKEN}" \ - "https://api.github.com/repos/${GITHUB_REPOSITORY}/releases/tags/${GITHUB_TAG}" + "https://api.github.com/repos/${GITHUB_REPOSITORY}/releases/tags/${TAG}" ` RELEASE_ID=`echo "${RELEASE_RESPONSE}" | jq '.id'` if [ "${RELEASE_ID}" = "null" ]; then - echo "creating release" - - COND_CREATE_DISCUSSION="" - PRERELEASE=true - if [[ ${GITHUB_TAG} =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - COND_CREATE_DISCUSSION="\"discussion_category_name\": \"announcement\"," - PRERELEASE=false - fi - - RELEASE_DATA="{ - \"tag_name\": \"${GITHUB_TAG}\", - \"target_commitish\": \"${GITHUB_SHA}\", - ${COND_CREATE_DISCUSSION} - \"name\": \"${GITHUB_TAG}\", - \"body\": \"\", - \"prerelease\": ${PRERELEASE} - }" - - # create it if it doesn't exist yet - RELEASE_RESPONSE=` - curl \ - --fail \ - --request POST \ - --header "Authorization: token ${GITHUB_TOKEN}" \ - --header "Content-Type: application/json" \ - --data "${RELEASE_DATA}" \ - "https://api.github.com/repos/${GITHUB_REPOSITORY}/releases" - ` -else - echo "release already exists" + echo "https://github.com/repos/${GITHUB_REPOSITORY}/releases/tags/${TAG} does not exist, publish failed" fi RELEASE_UPLOAD_URL=`echo "${RELEASE_RESPONSE}" | jq -r '.upload_url' | cut -d'{' -f1` diff --git a/scripts/version-check.sh b/scripts/version-check.sh deleted file mode 100755 index 4099c800ebb..00000000000 --- a/scripts/version-check.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env bash -set -ex - -# Validate lotus version matches the current tag -# $1 - lotus path to execute -# $2 - lotus git tag for this release -function validate_lotus_version_matches_tag(){ - # sanity checks - if [[ $# != 2 ]]; then - echo "expected 2 args for validate_lotus_version, got ${$#}" - exit 100 - fi - - # extract version from `lotus --version` response - lotus_path=$1 - # get version - lotus_raw_version=`${lotus_path} --version` - # grep for version string - lotus_actual_version=`echo ${lotus_raw_version} | grep -oE '[0-9]+\.[0-9]+\.[0-9]+'` - - # trim leading 'v' - tag=${2#v} - # trim possible -rc[0-9] - expected_version=${tag%-*} - - # check the versions are consistent - if [[ ${expected_version} != ${lotus_actual_version} ]]; then - echo "lotus version does not match build tag" - exit 101 - fi -} - -_lotus_path=$1 - -if [[ "$GITHUB_REF" == refs/tags/* ]]; then - validate_lotus_version_matches_tag "${_lotus_path}" "${GITHUB_REF#refs/tags/}" -else - echo "$GITHUB_REF is not a tag, skipping version check" -fi