diff --git a/SPECS/gh/0001-Fix-false-negative-in-TestMigrationWriteErrors-when-.patch b/SPECS/gh/0001-Fix-false-negative-in-TestMigrationWriteErrors-when-.patch new file mode 100644 index 00000000000..a3dc44dc3ee --- /dev/null +++ b/SPECS/gh/0001-Fix-false-negative-in-TestMigrationWriteErrors-when-.patch @@ -0,0 +1,88 @@ +From 82441ca6f9736bc542e699c8cbf46f80542ed618 Mon Sep 17 00:00:00 2001 +From: Vince Perri <5596945+vinceaperri@users.noreply.github.com> +Date: Tue, 19 Nov 2024 23:29:08 +0000 +Subject: [PATCH] Fix false-negative in TestMigrationWriteErrors when root + +--- + internal/config/migrate_test.go | 44 ++++++++++++++++++++++++++++++++- + 1 file changed, 43 insertions(+), 1 deletion(-) + +diff --git a/internal/config/migrate_test.go b/internal/config/migrate_test.go +index 783f605..7557149 100644 +--- a/internal/config/migrate_test.go ++++ b/internal/config/migrate_test.go +@@ -6,13 +6,20 @@ import ( + "io" + "os" + "path/filepath" ++ "syscall" + "testing" ++ "unsafe" + + ghmock "github.com/cli/cli/v2/internal/gh/mock" + ghConfig "github.com/cli/go-gh/v2/pkg/config" + "github.com/stretchr/testify/require" + ) + ++const ( ++ FS_IOC_SETFLAGS = 0x40086602 ++ FS_IMMUTABLE_FL = 0x00000010 ++) ++ + func TestMigrationAppliedSuccessfully(t *testing.T) { + readConfig := StubWriteConfig(t) + +@@ -215,6 +222,9 @@ func TestMigrationWriteErrors(t *testing.T) { + + // Then the error is wrapped and bubbled + require.ErrorContains(t, err, tt.wantErrContains) ++ ++ // Make the file writeable again so we can clean up ++ makeFileWriteable(t, filepath.Join(tempDir, tt.unwriteableFile)) + }) + } + } +@@ -226,7 +236,39 @@ func makeFileUnwriteable(t *testing.T, file string) { + require.NoError(t, err) + f.Close() + +- require.NoError(t, os.Chmod(file, 0000)) ++ if os.Geteuid() == 0 { ++ fd, err := syscall.Open(file, syscall.O_RDONLY, 0) ++ require.NoError(t, err) ++ defer syscall.Close(fd) ++ ++ var flags uint ++ _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(FS_IOC_SETFLAGS), uintptr(unsafe.Pointer(&flags))) ++ require.Zero(t, errno) ++ ++ flags |= FS_IMMUTABLE_FL ++ _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(FS_IOC_SETFLAGS), uintptr(unsafe.Pointer(&flags))) ++ require.Zero(t, errno) ++ } else { ++ require.NoError(t, os.Chmod(file, 0000)) ++ } ++} ++ ++func makeFileWriteable(t *testing.T, file string) { ++ t.Helper() ++ ++ if os.Geteuid() == 0 { ++ fd, err := syscall.Open(file, syscall.O_RDONLY, 0) ++ require.NoError(t, err) ++ defer syscall.Close(fd) ++ ++ var flags uint ++ _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(FS_IOC_SETFLAGS), uintptr(unsafe.Pointer(&flags))) ++ require.Zero(t, errno) ++ ++ flags &^= FS_IMMUTABLE_FL ++ _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(FS_IOC_SETFLAGS), uintptr(unsafe.Pointer(&flags))) ++ require.Zero(t, errno) ++ } + } + + func mockMigration(doFunc func(config *ghConfig.Config) error) *ghmock.MigrationMock { +-- +2.34.1 + diff --git a/SPECS/gh/generate_source_tarball.sh b/SPECS/gh/generate_source_tarball.sh new file mode 100755 index 00000000000..cc04d4b5189 --- /dev/null +++ b/SPECS/gh/generate_source_tarball.sh @@ -0,0 +1,168 @@ +#!/bin/bash +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# +# This script downloads the source tarball and uses it to generate the +# vendor tarball for the gh package. It also updates the package's +# signatures.json file for both tarballs, although it doesn't account for +# version changes. +# +# Notes: +# - You require GNU tar version 1.28+. +# - The additional options passed to tar enable generation of a tarball +# with the same hash every time regardless of the environment. See: +# https://reproducible-builds.org/docs/archives/ +# - For the value of "--mtime" we use the date "2021-04-26 00:00Z" to +# simplify future updates. +set -eu + +# get_spec_value extracts the parsed value of a tag from a spec file. +# - spec: The path to the spec file. +# - tag: The tag whose value is extracted. +# The extracted value is returned via stdout. +get_spec_value() { + local spec="$1" + local tag="$2" + local tmp=$(mktemp) + rpmspec -P "$spec" > "$tmp" + grep -E "^${tag}:" "$tmp" | sed -E "s/^$tag:\s*//" + rm "$tmp" +} + +# set_signature_value adds or updates the value of a signature in the +# signatures.json file. +# - signatures_json: The path to the signatures.json file. +# - path: The path to the file whose signature is updated. +set_signature_value() { + local signatures_json="$1" + local path="$2" + local name=$(basename "$path") + local sum=$(sha256sum "$path" | cut -d' ' -f1) + signatures_tmp=$(mktemp) + jq --indent 1 ".Signatures.\"$name\" = \"$sum\"" "$signatures_json" > "$signatures_tmp" + mv "$signatures_tmp" "$signatures_json" +} + +exit_usage() { + echo "Usage: $0 [flags]" + echo "" + echo "Flags:" + echo " --srcTarball src tarball file. If not provided, it will be downloaded according to the spec file." + echo " --outFolder folder where to copy the new tarball(s). If not provided, the tarballs will be copied to the same folder as the script." + echo " --pkgVersion package version. If not provided, it will be extracted from the spec file." + echo " --setSignature set the signature of the tarball(s) in the signatures.json file." + exit 2 +} + +arg_out_folder="" +arg_src_tarball="" +arg_pkg_version="" +arg_set_signatures=0 +while [[ $# -gt 0 ]]; do + case $1 in + -h|--help) + exit_usage + ;; + --outFolder) + # Convert to absolute path + arg_out_folder=$(readlink -f "$2") + shift + ;; + --srcTarball) + arg_src_tarball="$2" + shift + ;; + --pkgVersion) + arg_pkg_version="$2" + shift + ;; + --setSignature) + arg_set_signatures=1 + ;; + -*) + echo "Error: Unknown option: $1" + exit_usage + ;; + *) + echo "Error: Unknown argument: $1" + exit_usage + ;; + esac + + shift +done + +script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) + +out_folder="$arg_out_folder" +if [[ -z "$out_folder" ]]; then + out_folder="$script_dir" +elif [[ ! -d "$out_folder" ]]; then + echo "Error: The output folder does not exist." + exit 1 +fi + +spec_file=$(ls "$script_dir"/*.spec) + +src_tarball="$arg_src_tarball" +if [[ -z "$src_tarball" ]]; then + src_url=$(get_spec_value "$spec_file" "Source0") + if [[ -z "$src_url" ]]; then + echo "Error: Unable to determine the source0 URL from the spec file." + exit 1 + fi + + src_tarball_name=$(echo "$src_url" | grep -oP '(?<=#/)[^/]+') + if [[ -z "$src_tarball_name" ]]; then + echo "Error: Unable to determine the source0 tarball name from the source URL." + exit 1 + fi + + src_tarball="$script_dir/$src_tarball_name" + if [[ ! -f "$src_tarball" ]]; then + wget -O "$src_tarball" "$src_url" + fi +elif [[ ! -f "$src_tarball" ]]; then + echo "Error: The source tarball file does not exist." + exit 1 +fi + +pkg_name=$(get_spec_value "$spec_file" "Name") +if [[ -z "$pkg_name" ]]; then + echo "Error: Unable to determine the package name from the spec file." + exit 1 +fi + +pkg_version="$arg_pkg_version" +if [[ -z "$pkg_version" ]]; then + pkg_version=$(get_spec_value "$spec_file" "Version") + if [[ -z "$pkg_version" ]]; then + echo "Error: Unable to determine the package version from the spec file." + exit 1 + fi +fi + +# Extract the source tarball and generate the vendor tarball. +source_dir=$(mktemp -d) +trap "rm -rf '$source_dir'" EXIT +tar -C "$source_dir" -xf "$src_tarball" +cd "$source_dir"/* +go mod vendor +vendor_tarball="$out_folder/$pkg_name-$pkg_version-vendor.tar.gz" +tar --sort=name \ + --mtime="2021-04-26 00:00Z" \ + --owner=0 \ + --group=0 \ + --numeric-owner \ + --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime \ + -c \ + -f "$vendor_tarball" \ + vendor + +if [[ $arg_set_signatures -eq 1 ]]; then + signatures_file=$(ls "$script_dir"/*.signatures.json) + set_signature_value "$signatures_file" "$src_tarball" + set_signature_value "$signatures_file" "$vendor_tarball" +fi + +echo "Vendor tarball generated: $vendor_tarball" diff --git a/SPECS/gh/gh.signatures.json b/SPECS/gh/gh.signatures.json index 4ed8112994e..b5ec83df14b 100644 --- a/SPECS/gh/gh.signatures.json +++ b/SPECS/gh/gh.signatures.json @@ -1,6 +1,6 @@ { "Signatures": { - "cli-2.43.1.tar.gz": "1ea3f451fb7002c1fb95a7fab21e9ab16591058492628fe264c5878e79ec7c90", - "gh-2.43.1-vendor.tar.gz": "27791885c92900deae2baec254ada1d64d4dfabcfece5886a214f3279eb119f0" + "gh-2.62.0.tar.gz": "8b0d44a7fccd0c768d5ef7c3fbd274851b5752084e47761f146852de6539193e", + "gh-2.62.0-vendor.tar.gz": "2b39f75a9a45aa5e7b8d95e6b5fd7a11a7504e6cd7c92e904027f129abe48599" } } diff --git a/SPECS/gh/gh.spec b/SPECS/gh/gh.spec index a58348b95fd..a427d4ed703 100644 --- a/SPECS/gh/gh.spec +++ b/SPECS/gh/gh.spec @@ -1,33 +1,20 @@ Summary: GitHub official command line tool Name: gh -Version: 2.43.1 -Release: 2%{?dist} +Version: 2.62.0 +Release: 1%{?dist} License: MIT Vendor: Microsoft Corporation Distribution: Azure Linux Group: Applications/Tools URL: https://github.com/cli/cli -Source0: https://github.com/cli/cli/archive/refs/tags/v%{version}.tar.gz#/cli-%{version}.tar.gz -# Below is a manually created tarball, no download link. +Source0: https://github.com/cli/cli/archive/refs/tags/v%{version}.tar.gz#/%{name}-%{version}.tar.gz + +# Below is a manually created tarball, no download link. It is generated by running ./generate_source_tarball.sh. # We're using pre-populated Go modules from this tarball, since network is disabled during build time. -# How to re-build this file: -# 1. wget https://github.com/cli/cli/archive/refs/tags/v%{version}.tar.gz -O cli-%%{version}.tar.gz -# 2. tar -xf cli-%%{version}.tar.gz -# 3. cd cli-%%{version} -# 4. go mod vendor -# 5. tar --sort=name \ -# --mtime="2021-04-26 00:00Z" \ -# --owner=0 --group=0 --numeric-owner \ -# --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime \ -# -cf %%{name}-%%{version}-vendor.tar.gz vendor -# -# NOTES: -# - You require GNU tar version 1.28+. -# - The additional options enable generation of a tarball with the same hash every time regardless of the environment. -# See: https://reproducible-builds.org/docs/archives/ -# - For the value of "--mtime" use the date "2021-04-26 00:00Z" to simplify future updates. Source1: %{name}-%{version}-vendor.tar.gz +Patch0: 0001-Fix-false-negative-in-TestMigrationWriteErrors-when-.patch + BuildRequires: golang < 1.23 BuildRequires: git Requires: git @@ -70,6 +57,9 @@ make test %{_datadir}/zsh/site-functions/_gh %changelog +* Mon Nov 18 2024 Vince Perri - 2.62.0-1 +- Update to v2.62.0 + * Tue Oct 15 2024 Muhammad Falak - 2.43.1-2 - Pin golang version to <= 1.22 diff --git a/cgmanifest.json b/cgmanifest.json index 66a68e721c3..ca4564d91ed 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -4270,8 +4270,8 @@ "type": "other", "other": { "name": "gh", - "version": "2.43.1", - "downloadUrl": "https://github.com/cli/cli/archive/refs/tags/v2.43.1.tar.gz" + "version": "2.62.0", + "downloadUrl": "https://github.com/cli/cli/archive/refs/tags/v2.62.0.tar.gz" } } },