Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release: use GitHub's gh to create GitHub release #18649

Merged
merged 1 commit into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
Name-Email: [email protected]
Expire-Date: 0
EOF
DRY_RUN=true ./scripts/release.sh --no-upload --no-docker-push --in-place 3.6.99
DRY_RUN=true ./scripts/release.sh --no-upload --no-docker-push --no-gh-release --in-place 3.6.99
- name: test-image
run: |
VERSION=3.6.99 ./scripts/test_images.sh
Expand Down
11 changes: 4 additions & 7 deletions Documentation/contributor-guide/release.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ which don't need to be executed before releasing each version.
4. Authenticate the image registry, refer to [Authentication methods](https://cloud.google.com/container-registry/docs/advanced-authentication).
- `gcloud auth login`
- `gcloud auth configure-docker`
5. Install gh, refer to [GitHub's documentation](https://github.com/cli/cli#installation). Ensure that running
`gh auth login` succeeds for the GitHub account you use to contribute to etcd.

### Release steps

Expand All @@ -85,13 +87,8 @@ which don't need to be executed before releasing each version.
It generates all release binaries under the directory `/tmp/etcd-release-${VERSION}/etcd/release/` and images. Binaries are pushed to the Google Cloud bucket
under project `etcd-development`, and images are pushed to `quay.io` and `gcr.io`.
7. Publish the release page on GitHub
- Set the release title as the version name
- Choose the correct release tag (generated from step #4)
- Follow the format of previous release pages
- Attach the generated binaries and signature file
- Verify the historical binary size for each architecture. If there's a big difference, verify that it works for that architecture
- Select whether it's a pre-release
- Publish the release
- Open the **draft** release URL shown by the release script
- Review that it looks correct, then publish the release
8. Announce to the etcd-dev googlegroup

Follow the format of previous release emails sent to [email protected], see an example below. After sending out the email, ask one of the mailing list maintainers to approve the email from the pending list. Additionally, label the release email as `Release`.
Expand Down
96 changes: 88 additions & 8 deletions scripts/release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ help() {
echo "WARNING: This does not perform the 'Add API capabilities', 'Performance testing' "
echo " or 'Documentation' steps. These steps must be performed manually BEFORE running this tool."
echo ""
echo "WARNING: This script does not sign releases, publish releases to github or sent announcement"
echo " emails. These steps must be performed manually AFTER running this tool."
echo "WARNING: This script does not send announcement emails. This step must be performed manually AFTER running this tool."
echo ""
echo " args:"
echo " version: version of etcd to release, e.g. 'v3.2.18'"
echo " flags:"
echo " --no-upload: skip gs://etcd binary artifact uploads."
echo " --no-docker-push: skip docker image pushes."
echo " --in-place: build binaries using current branch."
echo " --no-docker-push: skip docker image pushes."
echo " --no-gh-release: skip creating the GitHub release using gh."
echo " --no-upload: skip gs://etcd binary artifact uploads."
echo ""
echo "One can perform a (dry-run) test release from any (uncommitted) branch using:"
echo " DRY_RUN=true REPOSITORY=\`pwd\` BRANCH='local-branch-name' ./scripts/release 3.5.0-foobar.2"
Expand Down Expand Up @@ -119,6 +119,21 @@ main() {
exit 1
fi

if [ "${NO_GH_RELEASE}" == 1 ]; then
log_callout "Skipping gh verification, --no-gh-release is set"
ivanvc marked this conversation as resolved.
Show resolved Hide resolved
else
# Check that gh is installed and logged in.
log_callout "Check gh installation"
if ! command -v gh >/dev/null; then
log_error "Cannot find gh. Please follow the installation instructions at https://github.com/cli/cli#installation"
exit 1
fi
if ! gh auth status &>/dev/null; then
log_error "GitHub authentication failed for gh. Please run gh auth login."
exit 1
fi
fi

# If the release tag does not already exist remotely, create it.
log_callout "Create tag if not present"
if [ "${remote_tag_exists}" -eq 0 ]; then
Expand Down Expand Up @@ -314,10 +329,70 @@ main() {
exit 1
fi

# TODO: signing process
log_warning ""
log_warning "WARNING: The release has not been signed and published to github. This must be done manually."
log_warning ""
if [ "${DRY_RUN}" == "true" ] || [ "${NO_GH_RELEASE}" == 1 ]; then
log_warning ""
log_warning "WARNING: Skipping creating GitHub release, --no-gh-release is set."
log_warning "WARNING: If not running on DRY_MODE, please do the GitHub release manually."
log_warning ""
else
local gh_repo
local release_notes_temp_file
local release_url
local gh_release_args=()

# For the main branch (v3.6), we should mark the release as a prerelease.
# The release-3.5 (v3.5) branch, should be marked as latest. And release-3.4 (v3.4)
# should be left without any additional mark (therefore, it doesn't need a special argument).
if [ "${BRANCH}" = "main" ]; then
gh_release_args=(--prerelease)
elif [ "${BRANCH}" = "release-3.5" ]; then
Copy link
Member

@serathius serathius Oct 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens when we release 3.6, and this will not updated? Maybe we should assert that branch name and fail that if new branch is cut we need to update which is the latest?

gh_release_args=(--latest)
fi

if [ "${REPOSITORY}" = "$(pwd)" ]; then
gh_repo=$(git remote get-url origin)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assumes that people cloned etcd main repo. If they cloned fork the origin would point to it. Is there any reason we cannot just skip it?

else
gh_repo="${REPOSITORY}"
fi

gh_repo=$(echo "${gh_repo}" | sed 's/^[^@]\+@//' | sed 's/https\?:\/\///' | sed 's/\.git$//' | tr ':' '/')
log_callout "Creating GitHub release for ${RELEASE_VERSION} on ${gh_repo}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really want to support pushing to other repositories?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re: this comment and #18649 (comment). I understand that we may want to drop supporting other repositories to simplify the process. However, the only reason I'd like to keep it, is that it's the only way to test locally without doing a release in etcd-io's repository (i.e., https://github.com/ivanvc/etcd/releases).

WDYT @jmhbnz, @ahrtr?

Copy link
Member

@jmhbnz jmhbnz Oct 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the ability to test in forks, let's keep it imo.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the ability to test in forks, let's keep it imo.

+1

Also it's just creating a draft release, and isn't published yet. It needs the release person to manually publish it.


release_notes_temp_file=$(mktemp)

local release_version=${RELEASE_VERSION#v} # Remove the v prefix from the release version (i.e., v3.6.1 -> 3.6.1)
local release_version_major_minor=${release_version%.*} # Remove the patch from the version (i.e., 3.6)
local release_version_major=${release_version_major_minor%.*} # Extract the major (i.e., 3)
local release_version_minor=${release_version_major_minor/*./} # Extract the minor (i.e., 6)

# Disable sellcheck SC2016, the single quoted syntax for sed is intentional.
# shellcheck disable=SC2016
sed 's/${RELEASE_VERSION}/'"${RELEASE_VERSION}"'/g' ./scripts/release_notes.tpl.txt |
sed 's/${RELEASE_VERSION_MAJOR_MINOR}/'"${release_version_major_minor}"'/g' |
sed 's/${RELEASE_VERSION_MAJOR}/'"${release_version_major}"'/g' |
sed 's/${RELEASE_VERSION_MINOR}/'"${release_version_minor}"'/g' > "${release_notes_temp_file}"

if ! gh --repo "${gh_repo}" release view "${RELEASE_VERSION}" &>/dev/null; then
maybe_run gh release create "${RELEASE_VERSION}" \
--repo "${gh_repo}" \
--draft \
--title "${RELEASE_VERSION}" \
--notes-file "${release_notes_temp_file}" \
"${gh_release_args[@]}"
fi

# Upload files one by one, as gh doesn't support passing globs as input.
maybe_run find ./release '(' -name '*.tar.gz' -o -name '*.zip' ')' -exec \
gh --repo "${gh_repo}" release upload "${RELEASE_VERSION}" {} --clobber \;
maybe_run gh --repo "${gh_repo}" release upload "${RELEASE_VERSION}" ./release/SHA256SUMS --clobber

release_url=$(gh --repo "${gh_repo}" release view "${RELEASE_VERSION}" --json url --jq '.url')

log_warning ""
log_warning "WARNING: The GitHub release for ${RELEASE_VERSION} has been created as a draft, please go to ${release_url} and release it."
log_warning ""
fi

log_success "Success."
exit 0
}
Expand All @@ -326,6 +401,7 @@ POSITIONAL=()
NO_UPLOAD=0
NO_DOCKER_PUSH=0
IN_PLACE=0
NO_GH_RELEASE=0

while test $# -gt 0; do
case "$1" in
Expand All @@ -346,6 +422,10 @@ while test $# -gt 0; do
NO_DOCKER_PUSH=1
shift
;;
--no-gh-release)
NO_GH_RELEASE=1
shift
;;
*)
POSITIONAL+=("$1") # save it in an array for later
shift # past argument
Expand Down
91 changes: 91 additions & 0 deletions scripts/release_notes.tpl.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
Please check out [CHANGELOG](https://github.com/etcd-io/etcd/blob/main/CHANGELOG/CHANGELOG-${RELEASE_VERSION_MAJOR_MINOR}.md) for a full list of changes. And make sure to read [upgrade guide](https://etcd.io/docs/v${RELEASE_VERSION_MAJOR_MINOR}/upgrades/upgrade_${RELEASE_VERSION_MAJOR}_${RELEASE_VERSION_MINOR}/) before upgrading etcd (there may be breaking changes).

For installation guides, please check out [play.etcd.io](http://play.etcd.io) and [operating etcd](https://etcd.io/docs/v${RELEASE_VERSION_MAJOR_MINOR}/op-guide/). Latest support status for common architectures and operating systems can be found at [supported platforms](https://etcd.io/docs/v${RELEASE_VERSION_MAJOR_MINOR}/op-guide/supported-platform/).

###### Linux

```sh
ETCD_VER=${RELEASE_VERSION}

# choose either URL
GOOGLE_URL=https://storage.googleapis.com/etcd
GITHUB_URL=https://github.com/etcd-io/etcd/releases/download
DOWNLOAD_URL=${GOOGLE_URL}

rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
rm -rf /tmp/etcd-download-test && mkdir -p /tmp/etcd-download-test

curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
tar xzvf /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz -C /tmp/etcd-download-test --strip-components=1
rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz

/tmp/etcd-download-test/etcd --version
/tmp/etcd-download-test/etcdctl version
/tmp/etcd-download-test/etcdutl version

# start a local etcd server
/tmp/etcd-download-test/etcd

# write,read to etcd
/tmp/etcd-download-test/etcdctl --endpoints=localhost:2379 put foo bar
/tmp/etcd-download-test/etcdctl --endpoints=localhost:2379 get foo
```

###### macOS (Darwin)

```sh
ETCD_VER=${RELEASE_VERSION}

# choose either URL
GOOGLE_URL=https://storage.googleapis.com/etcd
GITHUB_URL=https://github.com/etcd-io/etcd/releases/download
DOWNLOAD_URL=${GOOGLE_URL}

rm -f /tmp/etcd-${ETCD_VER}-darwin-amd64.zip
rm -rf /tmp/etcd-download-test && mkdir -p /tmp/etcd-download-test

curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-darwin-amd64.zip -o /tmp/etcd-${ETCD_VER}-darwin-amd64.zip
unzip /tmp/etcd-${ETCD_VER}-darwin-amd64.zip -d /tmp && rm -f /tmp/etcd-${ETCD_VER}-darwin-amd64.zip
mv /tmp/etcd-${ETCD_VER}-darwin-amd64/* /tmp/etcd-download-test && rm -rf mv /tmp/etcd-${ETCD_VER}-darwin-amd64

/tmp/etcd-download-test/etcd --version
/tmp/etcd-download-test/etcdctl version
/tmp/etcd-download-test/etcdutl version
```

###### Docker

etcd uses [`gcr.io/etcd-development/etcd`](https://gcr.io/etcd-development/etcd) as a primary container registry, and [`quay.io/coreos/etcd`](https://quay.io/coreos/etcd) as secondary.

```sh
ETCD_VER=${RELEASE_VERSION}

rm -rf /tmp/etcd-data.tmp && mkdir -p /tmp/etcd-data.tmp && \
docker rmi gcr.io/etcd-development/etcd:${ETCD_VER} || true && \
docker run \
-p 2379:2379 \
-p 2380:2380 \
--mount type=bind,source=/tmp/etcd-data.tmp,destination=/etcd-data \
--name etcd-gcr-${ETCD_VER} \
gcr.io/etcd-development/etcd:${ETCD_VER} \
/usr/local/bin/etcd \
--name s1 \
--data-dir /etcd-data \
--listen-client-urls http://0.0.0.0:2379 \
--advertise-client-urls http://0.0.0.0:2379 \
--listen-peer-urls http://0.0.0.0:2380 \
--initial-advertise-peer-urls http://0.0.0.0:2380 \
--initial-cluster s1=http://0.0.0.0:2380 \
--initial-cluster-token tkn \
--initial-cluster-state new \
--log-level info \
--logger zap \
--log-outputs stderr

docker exec etcd-gcr-${ETCD_VER}/usr/local/bin/etcd --version
docker exec etcd-gcr-${ETCD_VER}/usr/local/bin/etcdctl version
docker exec etcd-gcr-${ETCD_VER}/usr/local/bin/etcdutl version
docker exec etcd-gcr-${ETCD_VER}/usr/local/bin/etcdctl endpoint health
docker exec etcd-gcr-${ETCD_VER}/usr/local/bin/etcdctl put foo bar
docker exec etcd-gcr-${ETCD_VER}/usr/local/bin/etcdctl get foo
```
ivanvc marked this conversation as resolved.
Show resolved Hide resolved