chore: migrate to workspace structure and 3-file CI pipeline at toolkit 4.9.6
Signed-off-by: Jeremiah Russell <jerry@jrussell.ie>
This commit is contained in:
@@ -1,55 +1,16 @@
|
|||||||
version: 2.1
|
version: 2.1
|
||||||
|
|
||||||
parameters:
|
parameters:
|
||||||
fingerprint:
|
|
||||||
type: string
|
|
||||||
default: SHA256:OkxsH8Z6Iim6WDJBaII9eTT9aaO1f3eDc6IpsgYYPVg
|
|
||||||
min_rust_version:
|
min_rust_version:
|
||||||
type: string
|
type: string
|
||||||
default: "1.88"
|
default: "1.88"
|
||||||
release_flag:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
description: "If true, the release workflow will be executed."
|
|
||||||
success_flag:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
description: "If true, the success pipeline will be executed."
|
|
||||||
validation_flag:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
description: "If true, the validation pipeline will be executed."
|
|
||||||
|
|
||||||
orbs:
|
orbs:
|
||||||
toolkit: jerus-org/circleci-toolkit@4.4.2
|
toolkit: jerus-org/circleci-toolkit@4.9.6
|
||||||
|
|
||||||
# Custom executors removed - using toolkit rolling executors instead
|
|
||||||
|
|
||||||
workflows:
|
workflows:
|
||||||
check_last_commit:
|
|
||||||
when:
|
|
||||||
and:
|
|
||||||
- not:
|
|
||||||
equal: [scheduled_pipeline, << pipeline.trigger_source >>]
|
|
||||||
- not: << pipeline.parameters.success_flag >>
|
|
||||||
- not: << pipeline.parameters.release_flag >>
|
|
||||||
- not: << pipeline.parameters.validation_flag >>
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
- toolkit/choose_pipeline:
|
|
||||||
name: choose pipeline based on committer
|
|
||||||
context: bot-check
|
|
||||||
|
|
||||||
validation:
|
validation:
|
||||||
when:
|
|
||||||
and:
|
|
||||||
- not:
|
|
||||||
equal: [scheduled_pipeline, << pipeline.trigger_source >>]
|
|
||||||
- not: << pipeline.parameters.success_flag >>
|
|
||||||
- << pipeline.parameters.validation_flag >>
|
|
||||||
- not: << pipeline.parameters.release_flag >>
|
|
||||||
jobs:
|
jobs:
|
||||||
# Signature verification for trusted PRs (with write access for comments)
|
|
||||||
- toolkit/verify_commit_signatures:
|
- toolkit/verify_commit_signatures:
|
||||||
name: verify_commit_signatures_trusted
|
name: verify_commit_signatures_trusted
|
||||||
context: bot-check
|
context: bot-check
|
||||||
@@ -60,121 +21,63 @@ workflows:
|
|||||||
ignore:
|
ignore:
|
||||||
- main
|
- main
|
||||||
- /pull\/[0-9]+/
|
- /pull\/[0-9]+/
|
||||||
# Signature verification for forked PRs (read-only, no comments)
|
|
||||||
- toolkit/verify_commit_signatures:
|
- toolkit/verify_commit_signatures:
|
||||||
name: verify_commit_signatures_forked
|
name: verify_commit_signatures_forked
|
||||||
post_comment: false
|
post_comment: false
|
||||||
update_pcu: false
|
update_pcu: false
|
||||||
filters:
|
filters:
|
||||||
branches:
|
branches:
|
||||||
only: /pull\/[0-9]+/
|
only:
|
||||||
- toolkit/label:
|
- /pull\/[0-9]+/
|
||||||
|
|
||||||
|
- toolkit/required_builds_rolling:
|
||||||
min_rust_version: << pipeline.parameters.min_rust_version >>
|
min_rust_version: << pipeline.parameters.min_rust_version >>
|
||||||
context: pcu-app
|
|
||||||
update_pcu: true
|
- toolkit/optional_builds:
|
||||||
|
min_rust_version: << pipeline.parameters.min_rust_version >>
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
ignore: main
|
||||||
|
|
||||||
|
- toolkit/test_doc_build:
|
||||||
|
min_rust_version: << pipeline.parameters.min_rust_version >>
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
ignore: main
|
||||||
|
|
||||||
|
- toolkit/idiomatic_rust:
|
||||||
|
min_rust_version: << pipeline.parameters.min_rust_version >>
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
ignore: main
|
||||||
|
|
||||||
|
- toolkit/common_tests_rolling:
|
||||||
|
min_rust_version: << pipeline.parameters.min_rust_version >>
|
||||||
|
|
||||||
|
- toolkit/security:
|
||||||
|
name: security audit only
|
||||||
|
sonarcloud: false
|
||||||
filters:
|
filters:
|
||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- main
|
- main
|
||||||
- toolkit/required_builds:
|
- /pull\/[0-9]+/
|
||||||
min_rust_version: << pipeline.parameters.min_rust_version >>
|
|
||||||
- toolkit/optional_builds:
|
|
||||||
min_rust_version: << pipeline.parameters.min_rust_version >>
|
|
||||||
- toolkit/test_doc_build:
|
|
||||||
min_rust_version: << pipeline.parameters.min_rust_version >>
|
|
||||||
- toolkit/common_tests:
|
|
||||||
min_rust_version: << pipeline.parameters.min_rust_version >>
|
|
||||||
test_runner: nextest
|
|
||||||
nextest_profile: ci
|
|
||||||
post-steps:
|
|
||||||
- store_test_results:
|
|
||||||
path: target/nextest/ci/junit.xml
|
|
||||||
- toolkit/idiomatic_rust:
|
|
||||||
min_rust_version: << pipeline.parameters.min_rust_version >>
|
|
||||||
- toolkit/security:
|
|
||||||
name: security audit only
|
|
||||||
sonarcloud: false
|
|
||||||
ignore_advisories: RUSTSEC-2025-0066
|
|
||||||
filters:
|
|
||||||
branches:
|
|
||||||
only: /pull\/[0-9]+/
|
|
||||||
- toolkit/security:
|
- toolkit/security:
|
||||||
name: security with sonarcloud
|
name: security with sonarcloud
|
||||||
context: SonarCloud
|
context: SonarCloud
|
||||||
ignore_advisories: RUSTSEC-2025-0066
|
|
||||||
filters:
|
filters:
|
||||||
branches:
|
branches:
|
||||||
ignore:
|
ignore:
|
||||||
- /pull\/[0-9]+/
|
- /pull\/[0-9]+/
|
||||||
- main
|
- main
|
||||||
- toolkit/update_prlog:
|
|
||||||
|
- toolkit/code_coverage:
|
||||||
|
min_rust_version: << pipeline.parameters.min_rust_version >>
|
||||||
|
context: SonarCloud
|
||||||
filters:
|
filters:
|
||||||
branches:
|
branches:
|
||||||
ignore:
|
ignore:
|
||||||
- /pull\/[0-9]+/
|
- /pull\/[0-9]+/
|
||||||
- main
|
- main
|
||||||
requires:
|
|
||||||
- verify_commit_signatures_trusted
|
|
||||||
- toolkit/required_builds
|
|
||||||
- toolkit/test_doc_build
|
|
||||||
- toolkit/idiomatic_rust
|
|
||||||
- security audit only
|
|
||||||
- security with sonarcloud
|
|
||||||
- toolkit/common_tests
|
|
||||||
context:
|
|
||||||
- release
|
|
||||||
- bot-check
|
|
||||||
ssh_fingerprint: << pipeline.parameters.fingerprint >>
|
|
||||||
min_rust_version: << pipeline.parameters.min_rust_version >>
|
|
||||||
|
|
||||||
on_success:
|
|
||||||
when:
|
|
||||||
and:
|
|
||||||
- not:
|
|
||||||
equal: [scheduled_pipeline, << pipeline.trigger_source >>]
|
|
||||||
- << pipeline.parameters.success_flag >>
|
|
||||||
- not: << pipeline.parameters.validation_flag >>
|
|
||||||
- not: << pipeline.parameters.release_flag >>
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
- toolkit/end_success
|
|
||||||
|
|
||||||
release:
|
|
||||||
when:
|
|
||||||
and:
|
|
||||||
- or:
|
|
||||||
- and:
|
|
||||||
- equal: [scheduled_pipeline, << pipeline.trigger_source >>]
|
|
||||||
- equal: ["release check", << pipeline.schedule.name >>]
|
|
||||||
- << pipeline.parameters.release_flag >>
|
|
||||||
- not: << pipeline.parameters.success_flag >>
|
|
||||||
- not: << pipeline.parameters.validation_flag >>
|
|
||||||
jobs:
|
|
||||||
- toolkit/save_next_version:
|
|
||||||
min_rust_version: << pipeline.parameters.min_rust_version >>
|
|
||||||
|
|
||||||
- toolkit/make_release:
|
|
||||||
requires:
|
|
||||||
- toolkit/save_next_version
|
|
||||||
pre-steps:
|
|
||||||
- attach_workspace:
|
|
||||||
at: /tmp/workspace
|
|
||||||
- run:
|
|
||||||
name: Set SEMVER based on next-version file
|
|
||||||
command: |
|
|
||||||
set +ex
|
|
||||||
export SEMVER=$(cat /tmp/workspace/next-version)
|
|
||||||
echo $SEMVER
|
|
||||||
echo "export SEMVER=$SEMVER" >> "$BASH_ENV"
|
|
||||||
context:
|
|
||||||
- release
|
|
||||||
- bot-check
|
|
||||||
ssh_fingerprint: << pipeline.parameters.fingerprint >>
|
|
||||||
min_rust_version: << pipeline.parameters.min_rust_version >>
|
|
||||||
when_get_version: false
|
|
||||||
|
|
||||||
- toolkit/no_release:
|
|
||||||
min_rust_version: << pipeline.parameters.min_rust_version >>
|
|
||||||
requires:
|
|
||||||
- toolkit/save_next_version:
|
|
||||||
- failed
|
|
||||||
|
|||||||
@@ -1,419 +1,21 @@
|
|||||||
version: 2.1
|
version: 2.1
|
||||||
|
|
||||||
parameters:
|
parameters:
|
||||||
fingerprint:
|
cull_gmail_version:
|
||||||
type: string
|
|
||||||
default: SHA256:OkxsH8Z6Iim6WDJBaII9eTT9aaO1f3eDc6IpsgYYPVg
|
|
||||||
min_rust_version:
|
|
||||||
type: string
|
|
||||||
default: "1.88"
|
|
||||||
# Version override for crate release (used when nextsv cannot calculate)
|
|
||||||
# Set to empty string "" to use nextsv auto-detection
|
|
||||||
crate_version_override:
|
|
||||||
type: string
|
type: string
|
||||||
default: ""
|
default: ""
|
||||||
# Version override for workspace/PRLOG release
|
description: "Override cull-gmail crate version (empty = nextsv auto-detect)"
|
||||||
# Set to empty string "" to use nextsv auto-detection
|
workspace_version:
|
||||||
workspace_version_override:
|
|
||||||
type: string
|
type: string
|
||||||
default: ""
|
default: ""
|
||||||
|
description: "Override workspace v* version (empty = nextsv auto-detect)"
|
||||||
|
|
||||||
orbs:
|
orbs:
|
||||||
toolkit: jerus-org/circleci-toolkit@4.4.2
|
toolkit: jerus-org/circleci-toolkit@4.9.6
|
||||||
|
|
||||||
# Commands designed for future migration to circleci-toolkit
|
|
||||||
# These extend existing toolkit patterns with backward-compatible parameters
|
|
||||||
commands:
|
|
||||||
# New command: Check if version exists on crates.io
|
|
||||||
# Used for recovery scenarios where publish succeeded but workflow failed
|
|
||||||
check_crates_io_version:
|
|
||||||
description: >
|
|
||||||
Check if a version already exists on crates.io.
|
|
||||||
Sets SKIP_PUBLISH=true if version exists, false otherwise.
|
|
||||||
Used for recovery scenarios where crates.io publish succeeded but workflow failed afterward.
|
|
||||||
parameters:
|
|
||||||
package:
|
|
||||||
type: string
|
|
||||||
description: "Crate name on crates.io"
|
|
||||||
steps:
|
|
||||||
- run:
|
|
||||||
name: install kdeets
|
|
||||||
command: cargo install kdeets
|
|
||||||
- run:
|
|
||||||
name: Check crates.io for << parameters.package >>
|
|
||||||
command: |
|
|
||||||
set -eo pipefail
|
|
||||||
|
|
||||||
# Use SEMVER or NEXT_VERSION (whichever is set)
|
|
||||||
VERSION="${SEMVER:-${NEXT_VERSION:-none}}"
|
|
||||||
|
|
||||||
if [ "$VERSION" = "none" ]; then
|
|
||||||
echo "No version to check"
|
|
||||||
echo "export SKIP_PUBLISH=false" >> "$BASH_ENV"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
USER_AGENT="circleci-toolkit/1.0 (https://github.com/jerus-org/circleci-toolkit)"
|
|
||||||
|
|
||||||
most_recent_published="$(kdeets crate -br cull-gmail)"
|
|
||||||
|
|
||||||
if [[ ${most_recent_published} == ${VERSION} ]]; then
|
|
||||||
echo "Version ${VERSION} exists on crates.io - will skip publish"
|
|
||||||
echo "export SKIP_PUBLISH=true" >> "$BASH_ENV"
|
|
||||||
else
|
|
||||||
echo "Version ${VERSION} not found on crates.io - will publish"
|
|
||||||
echo "export SKIP_PUBLISH=false" >> "$BASH_ENV"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# New command: Check if release tag already exists
|
|
||||||
# Used for recovery scenarios where tag was created but workflow failed
|
|
||||||
check_tag_exists:
|
|
||||||
description: >
|
|
||||||
Check if the release tag already exists.
|
|
||||||
Sets SKIP_RELEASE=true if tag exists, false otherwise.
|
|
||||||
Used for recovery scenarios where release partially succeeded.
|
|
||||||
parameters:
|
|
||||||
package:
|
|
||||||
type: string
|
|
||||||
description: "Package name (used to construct tag name)"
|
|
||||||
steps:
|
|
||||||
- run:
|
|
||||||
name: Check if tag exists for << parameters.package >>
|
|
||||||
command: |
|
|
||||||
set -eo pipefail
|
|
||||||
|
|
||||||
# Use SEMVER or NEXT_VERSION (whichever is set)
|
|
||||||
VERSION="${SEMVER:-${NEXT_VERSION:-none}}"
|
|
||||||
|
|
||||||
if [ "$VERSION" = "none" ]; then
|
|
||||||
echo "No version to check"
|
|
||||||
echo "export SKIP_RELEASE=false" >> "$BASH_ENV"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "" = "<< parameters.package >>" ]; then
|
|
||||||
TAG="v${VERSION}"
|
|
||||||
else
|
|
||||||
TAG="<< parameters.package >>-v${VERSION}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Fetch tags from remote
|
|
||||||
git fetch --tags
|
|
||||||
|
|
||||||
if git tag -l "$TAG" | grep -q .; then
|
|
||||||
echo "Tag ${TAG} already exists - will skip release"
|
|
||||||
echo "export SKIP_RELEASE=true" >> "$BASH_ENV"
|
|
||||||
else
|
|
||||||
echo "Tag ${TAG} not found - will proceed with release"
|
|
||||||
echo "export SKIP_RELEASE=false" >> "$BASH_ENV"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Enhanced make_cargo_release with conditional publish support
|
|
||||||
# Backward compatible: publishes by default unless SKIP_PUBLISH=true or publish=false
|
|
||||||
# Also respects SKIP_RELEASE=true to skip entirely when tag already exists
|
|
||||||
make_cargo_release:
|
|
||||||
description: >
|
|
||||||
Make a release using cargo release.
|
|
||||||
Enhanced version that respects SKIP_PUBLISH environment variable for recovery scenarios.
|
|
||||||
When SKIP_PUBLISH=true, adds --no-publish flag to skip crates.io publish.
|
|
||||||
The publish parameter controls default behavior; SKIP_PUBLISH overrides it at runtime.
|
|
||||||
parameters:
|
|
||||||
package:
|
|
||||||
type: string
|
|
||||||
default: ""
|
|
||||||
description: "Package to release"
|
|
||||||
verbosity:
|
|
||||||
type: string
|
|
||||||
default: "-vv"
|
|
||||||
description: "Verbosity for cargo release"
|
|
||||||
publish:
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
description: "If true, the release will be published to crates.io"
|
|
||||||
no_push:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
description: "Whether cargo release should push the changes"
|
|
||||||
steps:
|
|
||||||
- run:
|
|
||||||
name: List changes using cargo release
|
|
||||||
command: |
|
|
||||||
set -exo pipefail
|
|
||||||
cargo release changes
|
|
||||||
- run:
|
|
||||||
name: Execute cargo release
|
|
||||||
command: |
|
|
||||||
set -exo pipefail
|
|
||||||
|
|
||||||
# Check if release should be skipped (tag already exists)
|
|
||||||
if [ "$SKIP_RELEASE" = "true" ]; then
|
|
||||||
echo "Skipping release (tag already exists)"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Use SEMVER or NEXT_VERSION
|
|
||||||
VERSION="${SEMVER:-${NEXT_VERSION:-none}}"
|
|
||||||
|
|
||||||
if [ "$VERSION" = "none" ]; then
|
|
||||||
echo "No version to release - skipping"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Releasing version: $VERSION"
|
|
||||||
|
|
||||||
# Build cargo release arguments
|
|
||||||
release_args="--execute --no-confirm --sign-tag"
|
|
||||||
|
|
||||||
if [ "<< parameters.package >>" != "" ]; then
|
|
||||||
release_args="$release_args --package << parameters.package >>"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "<< parameters.no_push >>" = "true" ]; then
|
|
||||||
release_args="$release_args --no-push"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Handle publish: parameter controls default, SKIP_PUBLISH overrides at runtime
|
|
||||||
if [ "<< parameters.publish >>" = "false" ]; then
|
|
||||||
release_args="$release_args --no-publish"
|
|
||||||
echo "Publishing disabled by parameter"
|
|
||||||
elif [ "$SKIP_PUBLISH" = "true" ]; then
|
|
||||||
release_args="$release_args --no-publish"
|
|
||||||
echo "Skipping publish (version already on crates.io)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Map verbosity
|
|
||||||
case "<< parameters.verbosity >>" in
|
|
||||||
"-vvv"|"-vvvv")
|
|
||||||
release_args="-vv $release_args"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
cargo release $release_args "$VERSION"
|
|
||||||
|
|
||||||
# Enhanced make_github_release with package support
|
|
||||||
make_github_release:
|
|
||||||
description: >
|
|
||||||
Create a GitHub release using the pcu utility.
|
|
||||||
When package is provided, uses 'pcu release package' which derives the correct tag prefix.
|
|
||||||
When package is empty, uses 'pcu release version' with the specified prefix.
|
|
||||||
parameters:
|
|
||||||
prefix:
|
|
||||||
type: string
|
|
||||||
default: "v"
|
|
||||||
description: "Tag prefix for the release (used when package is empty)"
|
|
||||||
package:
|
|
||||||
type: string
|
|
||||||
default: ""
|
|
||||||
description: "Package name - when provided, derives tag prefix automatically"
|
|
||||||
verbosity:
|
|
||||||
type: string
|
|
||||||
default: "-vv"
|
|
||||||
description: "Verbosity for pcu command"
|
|
||||||
update_prlog:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
description: "Update PRLOG when creating the release"
|
|
||||||
steps:
|
|
||||||
- run:
|
|
||||||
name: Create GitHub release
|
|
||||||
command: |
|
|
||||||
set -exo pipefail
|
|
||||||
|
|
||||||
# Use SEMVER or NEXT_VERSION
|
|
||||||
VERSION="${SEMVER:-${NEXT_VERSION:-none}}"
|
|
||||||
|
|
||||||
if [ "$VERSION" = "none" ]; then
|
|
||||||
echo "No version to release - skipping GitHub release"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Determine the tag name
|
|
||||||
if [ "<< parameters.package >>" != "" ]; then
|
|
||||||
TAG="<< parameters.package >>-v${VERSION}"
|
|
||||||
else
|
|
||||||
TAG="<< parameters.prefix >>${VERSION}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if GitHub release already exists using API
|
|
||||||
# Extract owner/repo from git remote
|
|
||||||
REPO_URL=$(git remote get-url origin)
|
|
||||||
REPO_PATH=$(echo "$REPO_URL" | sed -E 's|.*github\.com[:/]||' | sed 's|\.git$||')
|
|
||||||
|
|
||||||
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
|
|
||||||
-H "Authorization: token ${GITHUB_TOKEN}" \
|
|
||||||
-H "Accept: application/vnd.github.v3+json" \
|
|
||||||
"https://api.github.com/repos/${REPO_PATH}/releases/tags/${TAG}")
|
|
||||||
|
|
||||||
if [ "$HTTP_STATUS" = "200" ]; then
|
|
||||||
echo "GitHub release ${TAG} already exists - skipping"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
echo "GitHub release ${TAG} not found (HTTP ${HTTP_STATUS}) - will create"
|
|
||||||
|
|
||||||
pcu_args="<< parameters.verbosity >> release"
|
|
||||||
|
|
||||||
if [ "<< parameters.package >>" != "" ]; then
|
|
||||||
pcu_args="$pcu_args package << parameters.package >>"
|
|
||||||
else
|
|
||||||
pcu_args="$pcu_args --prefix << parameters.prefix >> version"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "<< parameters.update_prlog >>" = "true" ]; then
|
|
||||||
pcu_args="$pcu_args --update-prlog"
|
|
||||||
fi
|
|
||||||
|
|
||||||
pcu $pcu_args ${VERSION}
|
|
||||||
|
|
||||||
# Build a release binary using cargo.
|
|
||||||
# Requires VERSION environment variable (skips if "none").
|
|
||||||
build_release_binary:
|
|
||||||
description: >
|
|
||||||
Build a release-optimised binary using cargo build --release.
|
|
||||||
Expects VERSION to be set in BASH_ENV; skips when VERSION is "none".
|
|
||||||
steps:
|
|
||||||
- run:
|
|
||||||
name: Build release binary
|
|
||||||
command: |
|
|
||||||
set -eo pipefail
|
|
||||||
|
|
||||||
if [ "$VERSION" = "none" ]; then
|
|
||||||
echo "No version to release - skipping"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
cargo build --release
|
|
||||||
|
|
||||||
# Package a binary from target/release into a .tar.gz archive.
|
|
||||||
# Sets ASSET_NAME in BASH_ENV for use by upload_release_asset.
|
|
||||||
package_binary:
|
|
||||||
description: >
|
|
||||||
Package a binary from target/release into a .tar.gz archive named
|
|
||||||
<binary_name>-<target>.tar.gz. Sets ASSET_NAME in BASH_ENV.
|
|
||||||
parameters:
|
|
||||||
binary_name:
|
|
||||||
type: string
|
|
||||||
description: "Name of the binary in target/release"
|
|
||||||
target:
|
|
||||||
type: string
|
|
||||||
default: x86_64-unknown-linux-gnu
|
|
||||||
description: "Rust target triple for the archive name"
|
|
||||||
steps:
|
|
||||||
- run:
|
|
||||||
name: Package binary as tar.gz
|
|
||||||
command: |
|
|
||||||
set -eo pipefail
|
|
||||||
|
|
||||||
if [ "$VERSION" = "none" ]; then
|
|
||||||
echo "No version to release - skipping"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
ASSET_NAME="<< parameters.binary_name >>-<< parameters.target >>.tar.gz"
|
|
||||||
|
|
||||||
tar czf "$ASSET_NAME" -C target/release "<< parameters.binary_name >>"
|
|
||||||
echo "Created $ASSET_NAME ($(du -h "$ASSET_NAME" | cut -f1))"
|
|
||||||
|
|
||||||
echo "export ASSET_NAME=$ASSET_NAME" >> "$BASH_ENV"
|
|
||||||
|
|
||||||
# Upload a binary asset to a GitHub release.
|
|
||||||
# Adapted from toolkit/upload_release_asset with release_tag parameter
|
|
||||||
# so it works in pipelines where CIRCLE_TAG is not set.
|
|
||||||
# TODO: Replace with toolkit/upload_release_asset once it accepts a
|
|
||||||
# release_tag parameter (circleci-toolkit#333).
|
|
||||||
upload_release_asset:
|
|
||||||
description: >
|
|
||||||
Upload a binary asset to a GitHub release. Accepts a release_tag
|
|
||||||
parameter instead of relying on CIRCLE_TAG, making it usable in
|
|
||||||
scheduled/manual pipelines. Requires GITHUB_TOKEN environment variable.
|
|
||||||
parameters:
|
|
||||||
asset_path:
|
|
||||||
type: string
|
|
||||||
description: "Path to the asset file to upload"
|
|
||||||
asset_name:
|
|
||||||
type: string
|
|
||||||
default: ""
|
|
||||||
description: "Name for the asset in the release (defaults to filename)"
|
|
||||||
release_tag:
|
|
||||||
type: string
|
|
||||||
description: "Git tag identifying the GitHub release"
|
|
||||||
github_token_var:
|
|
||||||
type: env_var_name
|
|
||||||
default: GITHUB_TOKEN
|
|
||||||
description: "Environment variable containing the GitHub token"
|
|
||||||
steps:
|
|
||||||
- run:
|
|
||||||
name: Upload asset to GitHub release
|
|
||||||
command: |
|
|
||||||
set -eo pipefail
|
|
||||||
|
|
||||||
if [ "$VERSION" = "none" ]; then
|
|
||||||
echo "No version to release - skipping"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
ASSET_PATH="<< parameters.asset_path >>"
|
|
||||||
ASSET_NAME="<< parameters.asset_name >>"
|
|
||||||
TOKEN="${<< parameters.github_token_var >>}"
|
|
||||||
TAG="<< parameters.release_tag >>"
|
|
||||||
|
|
||||||
if [ -z "${ASSET_NAME}" ]; then
|
|
||||||
ASSET_NAME="$(basename "${ASSET_PATH}")"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -f "${ASSET_PATH}" ]; then
|
|
||||||
echo "ERROR: Asset file not found: ${ASSET_PATH}" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Derive repo slug from git remote
|
|
||||||
REPO_URL=$(git remote get-url origin)
|
|
||||||
REPO_SLUG=$(echo "$REPO_URL" | sed -E 's|.*github\.com[:/]||' | sed 's|\.git$||')
|
|
||||||
echo "Repository: ${REPO_SLUG}"
|
|
||||||
echo "Looking up release for tag ${TAG}..."
|
|
||||||
|
|
||||||
RELEASE_RESPONSE=$(curl -s -w "\n%{http_code}" \
|
|
||||||
-H "Authorization: Bearer ${TOKEN}" \
|
|
||||||
"https://api.github.com/repos/${REPO_SLUG}/releases/tags/${TAG}")
|
|
||||||
|
|
||||||
HTTP_CODE=$(echo "${RELEASE_RESPONSE}" | tail -1)
|
|
||||||
RELEASE_BODY=$(echo "${RELEASE_RESPONSE}" | sed '$d')
|
|
||||||
|
|
||||||
if [ "${HTTP_CODE}" != "200" ]; then
|
|
||||||
echo "ERROR: GitHub API returned HTTP ${HTTP_CODE}" >&2
|
|
||||||
echo "${RELEASE_BODY}" | jq -r '.message // .' >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
RELEASE_ID=$(echo "${RELEASE_BODY}" | jq -r '.id')
|
|
||||||
|
|
||||||
if [ -z "${RELEASE_ID}" ] || [ "${RELEASE_ID}" = "null" ]; then
|
|
||||||
echo "ERROR: Could not find GitHub release for tag ${TAG}" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Uploading ${ASSET_NAME} to release ${RELEASE_ID}..."
|
|
||||||
UPLOAD_RESPONSE=$(curl -s -w "\n%{http_code}" \
|
|
||||||
-X POST \
|
|
||||||
-H "Authorization: Bearer ${TOKEN}" \
|
|
||||||
-H "Content-Type: application/octet-stream" \
|
|
||||||
"https://uploads.github.com/repos/${REPO_SLUG}/releases/${RELEASE_ID}/assets?name=${ASSET_NAME}" \
|
|
||||||
--data-binary "@${ASSET_PATH}")
|
|
||||||
|
|
||||||
HTTP_CODE=$(echo "${UPLOAD_RESPONSE}" | tail -1)
|
|
||||||
UPLOAD_BODY=$(echo "${UPLOAD_RESPONSE}" | sed '$d')
|
|
||||||
|
|
||||||
if [ "${HTTP_CODE}" != "201" ]; then
|
|
||||||
echo "ERROR: Upload failed with HTTP ${HTTP_CODE}" >&2
|
|
||||||
echo "${UPLOAD_BODY}" | jq -r '.message // .' >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Upload complete: ${ASSET_NAME}"
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
tools:
|
tools:
|
||||||
executor:
|
executor: toolkit/rust_env_rolling
|
||||||
name: toolkit/rust_env_rolling
|
|
||||||
steps:
|
steps:
|
||||||
- run:
|
- run:
|
||||||
name: Verify tools
|
name: Verify tools
|
||||||
@@ -423,314 +25,39 @@ jobs:
|
|||||||
pcu --version
|
pcu --version
|
||||||
cargo release --version
|
cargo release --version
|
||||||
jq --version
|
jq --version
|
||||||
|
rsign --version
|
||||||
# Calculate and display versions for approval
|
|
||||||
# Persists calculated versions to workspace for downstream jobs
|
|
||||||
calculate-versions:
|
|
||||||
parameters:
|
|
||||||
crate_version:
|
|
||||||
type: string
|
|
||||||
default: ""
|
|
||||||
description: "Override version for crate release (empty = auto-detect)"
|
|
||||||
workspace_version:
|
|
||||||
type: string
|
|
||||||
default: ""
|
|
||||||
description: "Override version for workspace/PRLOG release (empty = auto-detect)"
|
|
||||||
executor:
|
|
||||||
name: toolkit/rust_env_rolling
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
- run:
|
|
||||||
name: Calculate release versions
|
|
||||||
command: |
|
|
||||||
set -eo pipefail
|
|
||||||
|
|
||||||
echo "=============================================="
|
|
||||||
echo " RELEASE VERSION CALCULATION"
|
|
||||||
echo "=============================================="
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Check for version override (passed from workflow)
|
|
||||||
VERSION_OVERRIDE="<< parameters.crate_version >>"
|
|
||||||
|
|
||||||
# Calculate crate version
|
|
||||||
echo "--- Crate: cull-gmail ---"
|
|
||||||
if [ -n "$VERSION_OVERRIDE" ]; then
|
|
||||||
CRATE_VERSION="$VERSION_OVERRIDE"
|
|
||||||
echo "Result: Will release version $CRATE_VERSION (OVERRIDE)"
|
|
||||||
echo "Note: Version explicitly set via crate_version parameter"
|
|
||||||
NEXTSV_VERSION=$(nextsv -bn calculate 2>/dev/null || echo "none")
|
|
||||||
echo " (nextsv would have calculated: $NEXTSV_VERSION)"
|
|
||||||
else
|
|
||||||
CRATE_VERSION=$(nextsv -bn calculate 2>/dev/null || echo "")
|
|
||||||
if [ -z "$CRATE_VERSION" ]; then
|
|
||||||
CRATE_VERSION="none"
|
|
||||||
echo "Result: No crate release needed"
|
|
||||||
echo "Reason: No changes to crates/cull-gmail/ or its dependencies"
|
|
||||||
else
|
|
||||||
echo "Result: Will release version $CRATE_VERSION"
|
|
||||||
echo "Changes detected in crate scope (code, deps, or Cargo.lock)"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Calculate workspace version
|
|
||||||
echo "--- Workspace (PRLOG) ---"
|
|
||||||
WORKSPACE_OVERRIDE="<< parameters.workspace_version >>"
|
|
||||||
if [ -n "$WORKSPACE_OVERRIDE" ]; then
|
|
||||||
WORKSPACE_VERSION="$WORKSPACE_OVERRIDE"
|
|
||||||
echo "Result: Will release version $WORKSPACE_VERSION (OVERRIDE)"
|
|
||||||
echo "Note: Version explicitly set via workspace_version parameter"
|
|
||||||
NEXTSV_WS=$(nextsv -bn calculate --prefix "v" 2>/dev/null || echo "none")
|
|
||||||
echo " (nextsv would have calculated: $NEXTSV_WS)"
|
|
||||||
else
|
|
||||||
WORKSPACE_VERSION=$(nextsv -bn calculate --prefix "v" 2>/dev/null || echo "")
|
|
||||||
if [ -z "$WORKSPACE_VERSION" ]; then
|
|
||||||
WORKSPACE_VERSION="none"
|
|
||||||
echo "Result: No workspace release needed"
|
|
||||||
echo "Reason: No changes since last v* tag"
|
|
||||||
else
|
|
||||||
echo "Result: Will release version $WORKSPACE_VERSION"
|
|
||||||
echo "Changes detected in workspace scope"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo "=============================================="
|
|
||||||
echo " SUMMARY"
|
|
||||||
echo "=============================================="
|
|
||||||
echo "Crate (cull-gmail): $CRATE_VERSION"
|
|
||||||
echo "Workspace (PRLOG): $WORKSPACE_VERSION"
|
|
||||||
echo "=============================================="
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Validation rules
|
|
||||||
echo "--- Validation ---"
|
|
||||||
if [ "$CRATE_VERSION" != "none" ] && [ "$WORKSPACE_VERSION" = "none" ]; then
|
|
||||||
echo "WARNING: Crate release without workspace release is unusual"
|
|
||||||
echo " Workspace should increment when crate changes"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$CRATE_VERSION" = "none" ] && [ "$WORKSPACE_VERSION" = "none" ]; then
|
|
||||||
echo "INFO: No releases needed - workflow will skip release steps"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "Please review the versions above and approve to proceed."
|
|
||||||
|
|
||||||
# Persist versions to workspace for downstream jobs
|
|
||||||
mkdir -p /tmp/release-versions
|
|
||||||
echo "$CRATE_VERSION" > /tmp/release-versions/crate-version
|
|
||||||
echo "$WORKSPACE_VERSION" > /tmp/release-versions/workspace-version
|
|
||||||
echo "Versions persisted to workspace for release jobs"
|
|
||||||
- persist_to_workspace:
|
|
||||||
root: /tmp
|
|
||||||
paths:
|
|
||||||
- release-versions
|
|
||||||
|
|
||||||
# Release a single crate
|
|
||||||
# Reads version from workspace (calculated by calculate-versions job)
|
|
||||||
release-crate:
|
|
||||||
parameters:
|
|
||||||
package:
|
|
||||||
type: string
|
|
||||||
default: ""
|
|
||||||
executor:
|
|
||||||
name: toolkit/rust_env_rolling
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
- attach_workspace:
|
|
||||||
at: /tmp
|
|
||||||
- add_ssh_keys:
|
|
||||||
fingerprints:
|
|
||||||
- << pipeline.parameters.fingerprint >>
|
|
||||||
- run:
|
|
||||||
name: Remove original SSH key from agent
|
|
||||||
command: |
|
|
||||||
ssh-add -l
|
|
||||||
# GitHub App integration doesn't create id_rsa.pub, handle gracefully
|
|
||||||
if [ -f ~/.ssh/id_rsa.pub ]; then
|
|
||||||
ssh-add -d ~/.ssh/id_rsa.pub
|
|
||||||
else
|
|
||||||
echo "No id_rsa.pub found (GitHub App integration) - skipping removal"
|
|
||||||
fi
|
|
||||||
ssh-add -l
|
|
||||||
- toolkit/gpg_key
|
|
||||||
- toolkit/git_config
|
|
||||||
# Step 1: Load version from workspace (calculated by calculate-versions)
|
|
||||||
- run:
|
|
||||||
name: Load version from workspace
|
|
||||||
command: |
|
|
||||||
set -eo pipefail
|
|
||||||
VERSION_FILE="/tmp/release-versions/crate-version"
|
|
||||||
if [ -f "$VERSION_FILE" ]; then
|
|
||||||
VERSION=$(cat "$VERSION_FILE")
|
|
||||||
echo "Loaded version from workspace: $VERSION"
|
|
||||||
echo "export NEXT_VERSION=$VERSION" >> "$BASH_ENV"
|
|
||||||
echo "export SEMVER=$VERSION" >> "$BASH_ENV"
|
|
||||||
else
|
|
||||||
echo "ERROR: Version file not found at $VERSION_FILE"
|
|
||||||
echo "This job requires calculate-versions to run first"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
# Step 2: Check crates.io for recovery scenarios
|
|
||||||
- check_crates_io_version:
|
|
||||||
package: << parameters.package >>
|
|
||||||
# Step 3: Check if tag already exists for recovery scenarios
|
|
||||||
- check_tag_exists:
|
|
||||||
package: << parameters.package >>
|
|
||||||
# Step 4: Run cargo release (respects SKIP_PUBLISH and SKIP_RELEASE)
|
|
||||||
- make_cargo_release:
|
|
||||||
package: << parameters.package >>
|
|
||||||
verbosity: "-vv"
|
|
||||||
# Step 5: Update pcu to latest version (command not yet in toolkit release)
|
|
||||||
- run:
|
|
||||||
name: Update to latest pcu
|
|
||||||
command: |
|
|
||||||
cargo install --force --git https://github.com/jerus-org/pcu --branch main
|
|
||||||
# Step 6: Create GitHub release
|
|
||||||
- make_github_release:
|
|
||||||
package: << parameters.package >>
|
|
||||||
verbosity: "-vv"
|
|
||||||
|
|
||||||
# # Release PRLOG/workspace
|
|
||||||
# # Reads version from workspace (calculated by calculate-versions job)
|
|
||||||
# release-prlog:
|
|
||||||
# executor:
|
|
||||||
# name: toolkit/rust_env_rolling
|
|
||||||
# steps:
|
|
||||||
# - checkout
|
|
||||||
# - attach_workspace:
|
|
||||||
# at: /tmp
|
|
||||||
# - add_ssh_keys:
|
|
||||||
# fingerprints:
|
|
||||||
# - << pipeline.parameters.fingerprint >>
|
|
||||||
# - run:
|
|
||||||
# name: Remove original SSH key from agent
|
|
||||||
# command: |
|
|
||||||
# ssh-add -l
|
|
||||||
# # GitHub App integration doesn't create id_rsa.pub, handle gracefully
|
|
||||||
# if [ -f ~/.ssh/id_rsa.pub ]; then
|
|
||||||
# ssh-add -d ~/.ssh/id_rsa.pub
|
|
||||||
# else
|
|
||||||
# echo "No id_rsa.pub found (GitHub App integration) - skipping removal"
|
|
||||||
# fi
|
|
||||||
# ssh-add -l
|
|
||||||
# - toolkit/gpg_key
|
|
||||||
# - toolkit/git_config
|
|
||||||
# - run:
|
|
||||||
# name: Release PRLOG
|
|
||||||
# command: |
|
|
||||||
# set -exo pipefail
|
|
||||||
# chmod +x scripts/*.sh
|
|
||||||
|
|
||||||
# # Load version from workspace (calculated by calculate-versions)
|
|
||||||
# VERSION_FILE="/tmp/release-versions/workspace-version"
|
|
||||||
# if [ -f "$VERSION_FILE" ]; then
|
|
||||||
# VERSION=$(cat "$VERSION_FILE")
|
|
||||||
# echo "Loaded workspace version from workspace: $VERSION"
|
|
||||||
# else
|
|
||||||
# echo "ERROR: Version file not found at $VERSION_FILE"
|
|
||||||
# echo "This job requires calculate-versions to run first"
|
|
||||||
# exit 1
|
|
||||||
# fi
|
|
||||||
|
|
||||||
# if [ "$VERSION" = "none" ]; then
|
|
||||||
# echo "No PRLOG release needed"
|
|
||||||
# exit 0
|
|
||||||
# fi
|
|
||||||
|
|
||||||
# # Check if tag already exists
|
|
||||||
# TAG="v${VERSION}"
|
|
||||||
# git fetch --tags origin main
|
|
||||||
|
|
||||||
# # Pull latest main (release-crate may have pushed commits)
|
|
||||||
# git pull --rebase origin main
|
|
||||||
|
|
||||||
# if git tag -l "$TAG" | grep -q .; then
|
|
||||||
# echo "Tag $TAG already exists - updating PRLOG without new tag"
|
|
||||||
# # Update PRLOG.md with the release date but don't create new tag
|
|
||||||
# ./scripts/release-prlog.sh "$VERSION" --no-tag 2>/dev/null || \
|
|
||||||
# ./scripts/release-prlog.sh "$VERSION"
|
|
||||||
# git push origin main || echo "No changes to push"
|
|
||||||
# else
|
|
||||||
# echo "Creating new release for version $VERSION"
|
|
||||||
# ./scripts/release-prlog.sh "$VERSION"
|
|
||||||
# git push origin main --tags
|
|
||||||
# fi
|
|
||||||
|
|
||||||
# Build release binary and upload to GitHub release for cargo-binstall
|
|
||||||
release-binary:
|
|
||||||
executor:
|
|
||||||
name: toolkit/rust_env_rolling
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
- attach_workspace:
|
|
||||||
at: /tmp
|
|
||||||
- run:
|
|
||||||
name: Load version from workspace
|
|
||||||
command: |
|
|
||||||
set -eo pipefail
|
|
||||||
VERSION_FILE="/tmp/release-versions/crate-version"
|
|
||||||
if [ -f "$VERSION_FILE" ]; then
|
|
||||||
VERSION=$(cat "$VERSION_FILE")
|
|
||||||
echo "Loaded version from workspace: $VERSION"
|
|
||||||
echo "export VERSION=$VERSION" >> "$BASH_ENV"
|
|
||||||
else
|
|
||||||
echo "ERROR: Version file not found at $VERSION_FILE"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
- build_release_binary
|
|
||||||
- package_binary:
|
|
||||||
binary_name: cull-gmail
|
|
||||||
- upload_release_asset:
|
|
||||||
asset_path: cull-gmail-x86_64-unknown-linux-gnu.tar.gz
|
|
||||||
release_tag: v${VERSION}
|
|
||||||
|
|
||||||
workflows:
|
workflows:
|
||||||
release:
|
release:
|
||||||
jobs:
|
jobs:
|
||||||
- tools
|
- tools
|
||||||
|
|
||||||
# Calculate and display versions for review
|
- toolkit/calculate_versions:
|
||||||
# Pass pipeline parameters to job for version overrides
|
name: calculate-versions
|
||||||
- calculate-versions:
|
|
||||||
requires: [tools]
|
requires: [tools]
|
||||||
crate_version: << pipeline.parameters.crate_version_override >>
|
crates: "cull-gmail:cull-gmail-v"
|
||||||
workspace_version: << pipeline.parameters.workspace_version_override >>
|
crate_version_overrides: "cull-gmail:<< pipeline.parameters.cull_gmail_version >>"
|
||||||
|
workspace_version_override: << pipeline.parameters.workspace_version >>
|
||||||
|
|
||||||
# Manual approval gate - review calculated versions before release
|
|
||||||
- approve-release:
|
- approve-release:
|
||||||
type: approval
|
type: approval
|
||||||
requires: [calculate-versions]
|
requires: [calculate-versions]
|
||||||
|
|
||||||
# Release cull-gmail crate
|
- toolkit/release_crate:
|
||||||
# Version is read from workspace (set by calculate-versions)
|
|
||||||
# Pipeline parameter crate_version_override controls the override
|
|
||||||
# Set parameter to "" to resume nextsv auto-detection
|
|
||||||
- release-crate:
|
|
||||||
name: release-cull-gmail
|
name: release-cull-gmail
|
||||||
requires: [approve-release]
|
requires: [approve-release]
|
||||||
|
package: cull-gmail
|
||||||
|
crate_tag_prefix: cull-gmail-v
|
||||||
|
build_binary: true
|
||||||
|
binary_name: cull-gmail
|
||||||
context:
|
context:
|
||||||
- release
|
- release
|
||||||
- bot-check
|
- bot-check
|
||||||
|
- pcu-app
|
||||||
|
|
||||||
# Build and upload release binary for cargo-binstall
|
- toolkit/release_prlog:
|
||||||
- release-binary:
|
|
||||||
requires: [release-cull-gmail]
|
requires: [release-cull-gmail]
|
||||||
context:
|
context:
|
||||||
- release
|
- release
|
||||||
- bot-check
|
- bot-check
|
||||||
|
- pcu-app
|
||||||
# Release PRLOG (after crate released)
|
|
||||||
- toolkit/make_release:
|
|
||||||
requires: [release-cull-gmail]
|
|
||||||
context:
|
|
||||||
- release
|
|
||||||
- bot-check
|
|
||||||
ssh_fingerprint: << pipeline.parameters.fingerprint >>
|
|
||||||
min_rust_version: << pipeline.parameters.min_rust_version >>
|
|
||||||
when_cargo_release: false
|
|
||||||
when_use_workspace: false
|
|
||||||
pcu_update_prlog: true
|
|
||||||
remove_ssh_key: false
|
|
||||||
|
|||||||
30
.circleci/update_prlog.yml
Normal file
30
.circleci/update_prlog.yml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
version: 2.1
|
||||||
|
|
||||||
|
parameters:
|
||||||
|
update_pcu:
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
description: "If true, pcu is updated from its main github branch before running."
|
||||||
|
|
||||||
|
orbs:
|
||||||
|
toolkit: jerus-org/circleci-toolkit@4.9.6
|
||||||
|
|
||||||
|
workflows:
|
||||||
|
update_prlog:
|
||||||
|
jobs:
|
||||||
|
- toolkit/update_prlog:
|
||||||
|
name: update-prlog-on-main
|
||||||
|
context:
|
||||||
|
- release
|
||||||
|
- bot-check
|
||||||
|
- pcu-app
|
||||||
|
min_rust_version: "1.88"
|
||||||
|
target_branch: "main"
|
||||||
|
pcu_from_merge: --from-merge
|
||||||
|
update_pcu: << pipeline.parameters.update_pcu >>
|
||||||
|
pcu_verbosity: "-vvv"
|
||||||
|
- toolkit/label:
|
||||||
|
min_rust_version: "1.88"
|
||||||
|
context: pcu-app
|
||||||
|
requires:
|
||||||
|
- update-prlog-on-main
|
||||||
72
Cargo.toml
72
Cargo.toml
@@ -1,73 +1,49 @@
|
|||||||
[package]
|
[workspace]
|
||||||
name = "cull-gmail"
|
members = ["crates/cull-gmail"]
|
||||||
description = "Cull emails from a gmail account using the gmail API"
|
resolver = "2"
|
||||||
version = "0.1.4"
|
|
||||||
authors = ["Jeremiah Russell <jrussell@jerus.ie>"]
|
[workspace.package]
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
authors = ["Jeremiah Russell <jrussell@jerus.ie>"]
|
||||||
rust-version = "1.88"
|
rust-version = "1.88"
|
||||||
|
license = "MIT"
|
||||||
|
repository = "https://github.com/jerus-org/cull-gmail"
|
||||||
keywords = ["gmail", "gmail-api", "management"]
|
keywords = ["gmail", "gmail-api", "management"]
|
||||||
categories = ["command-line-utilities"]
|
categories = ["command-line-utilities"]
|
||||||
license = "MIT"
|
|
||||||
readme = "README.md"
|
|
||||||
repository = "https://github.com/jerus-org/cull-gmail"
|
|
||||||
include = [
|
|
||||||
"**/*.rs",
|
|
||||||
"Cargo.toml",
|
|
||||||
"README.md",
|
|
||||||
"LICENSE-MIT",
|
|
||||||
"LICENSE-APACHE",
|
|
||||||
"CHANGELOG.md",
|
|
||||||
"docs",
|
|
||||||
]
|
|
||||||
|
|
||||||
[dependencies]
|
[workspace.dependencies]
|
||||||
|
base64 = "0.22.1"
|
||||||
chrono = "0.4.43"
|
chrono = "0.4.43"
|
||||||
clap = { version = "4.5.58", features = ["derive"] }
|
clap = { version = "4.5.58", features = ["derive"] }
|
||||||
clap-verbosity-flag = { version = "3.0.4", features = ["tracing"] }
|
clap-verbosity-flag = { version = "3.0.4", features = ["tracing"] }
|
||||||
config = { version = "0.15.19", default-features = false, features = [
|
config = { version = "0.15.19", default-features = false, features = ["json", "toml"] }
|
||||||
"json",
|
dialoguer = "0.12.0"
|
||||||
"toml",
|
|
||||||
] }
|
|
||||||
env_logger = "0.11.9"
|
env_logger = "0.11.9"
|
||||||
|
flate2 = "1.1.9"
|
||||||
|
futures = "0.3.31"
|
||||||
google-gmail1 = { version = "7.0.0", default-features = false, features = ["yup-oauth2", "aws-lc-rs"] }
|
google-gmail1 = { version = "7.0.0", default-features = false, features = ["yup-oauth2", "aws-lc-rs"] }
|
||||||
hyper-rustls = { version = "0.27.7", features = ["http1"] }
|
hyper-rustls = { version = "0.27.7", features = ["http1"] }
|
||||||
|
indicatif = "0.18.3"
|
||||||
lazy-regex = "3.6.0"
|
lazy-regex = "3.6.0"
|
||||||
log = "0.4.29"
|
log = "0.4.29"
|
||||||
serde = { version = "1.0.228", features = ["derive"] }
|
serde = { version = "1.0.228", features = ["derive"] }
|
||||||
serde_json = "1.0.149"
|
serde_json = "1.0.149"
|
||||||
thiserror = "2.0.18"
|
thiserror = "2.0.18"
|
||||||
tokio = { version = "1.49.0", features = [
|
tokio = { version = "1.49.0", features = ["macros", "rt-multi-thread", "process"] }
|
||||||
"macros",
|
|
||||||
"rt-multi-thread",
|
|
||||||
"process",
|
|
||||||
] }
|
|
||||||
toml = "1.0.0"
|
toml = "1.0.0"
|
||||||
base64 = "0.22.1"
|
|
||||||
flate2 = "1.1.9"
|
|
||||||
dialoguer = "0.12.0"
|
|
||||||
indicatif = "0.18.3"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
# dev-dependencies
|
||||||
httpmock = "0.8.3"
|
|
||||||
tokio-test = "0.4.5"
|
|
||||||
temp-env = "0.3.6"
|
|
||||||
tempfile = "3.25.0"
|
|
||||||
futures = "0.3.31"
|
|
||||||
assert_cmd = "2.1.2"
|
assert_cmd = "2.1.2"
|
||||||
assert_fs = "1.1.3"
|
assert_fs = "1.1.3"
|
||||||
|
httpmock = "0.8.3"
|
||||||
predicates = "3.1.4"
|
predicates = "3.1.4"
|
||||||
|
temp-env = "0.3.6"
|
||||||
|
tempfile = "3.25.0"
|
||||||
|
tokio-test = "0.4.5"
|
||||||
|
|
||||||
[lints.clippy]
|
[workspace.lints.clippy]
|
||||||
uninlined-format-args = "warn"
|
uninlined-format-args = "warn"
|
||||||
unnecessary_semicolon = "warn"
|
unnecessary_semicolon = "warn"
|
||||||
|
|
||||||
[lints.rust]
|
[workspace.lints.rust]
|
||||||
dead-code = "allow" # allow temporarily while developing initial code
|
dead-code = "allow"
|
||||||
|
|
||||||
[lib]
|
|
||||||
name = "cull_gmail"
|
|
||||||
path = "src/lib.rs"
|
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "cull-gmail"
|
|
||||||
path = "src/cli/main.rs"
|
|
||||||
|
|||||||
7
PRLOG.md
7
PRLOG.md
@@ -5,6 +5,8 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
## [0.1.4] - 2026-02-14
|
## [0.1.4] - 2026-02-14
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
@@ -477,8 +479,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
[#161]: https://github.com/jerus-org/cull-gmail/pull/161
|
[#161]: https://github.com/jerus-org/cull-gmail/pull/161
|
||||||
[#162]: https://github.com/jerus-org/cull-gmail/pull/162
|
[#162]: https://github.com/jerus-org/cull-gmail/pull/162
|
||||||
[#163]: https://github.com/jerus-org/cull-gmail/pull/163
|
[#163]: https://github.com/jerus-org/cull-gmail/pull/163
|
||||||
[0.1.4]: https://github.com/jerus-org/cull-gmail/compare/v0.1.3...v0.1.4
|
[Unreleased]: https://github.com/jerus-org/cull-gmail/compare/cull-gmail-v0.1.4...HEAD
|
||||||
[0.1.3]: https://github.com/jerus-org/cull-gmail/compare/v0.1.2...v0.1.3
|
[0.1.4]: https://github.com/jerus-org/cull-gmail/compare/cull-gmail-v0.1.3...cull-gmail-v0.1.4
|
||||||
|
[0.1.3]: https://github.com/jerus-org/cull-gmail/compare/cull-gmail-v0.1.2...cull-gmail-v0.1.3
|
||||||
[0.1.2]: https://github.com/jerus-org/cull-gmail/compare/v0.1.1...v0.1.2
|
[0.1.2]: https://github.com/jerus-org/cull-gmail/compare/v0.1.1...v0.1.2
|
||||||
[0.1.1]: https://github.com/jerus-org/cull-gmail/compare/v0.1.0...v0.1.1
|
[0.1.1]: https://github.com/jerus-org/cull-gmail/compare/v0.1.0...v0.1.1
|
||||||
[0.1.0]: https://github.com/jerus-org/cull-gmail/compare/v0.0.16...v0.1.0
|
[0.1.0]: https://github.com/jerus-org/cull-gmail/compare/v0.0.16...v0.1.0
|
||||||
|
|||||||
62
crates/cull-gmail/Cargo.toml
Normal file
62
crates/cull-gmail/Cargo.toml
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
[package]
|
||||||
|
name = "cull-gmail"
|
||||||
|
description = "Cull emails from a gmail account using the gmail API"
|
||||||
|
version = "0.1.4"
|
||||||
|
edition.workspace = true
|
||||||
|
authors.workspace = true
|
||||||
|
rust-version.workspace = true
|
||||||
|
license.workspace = true
|
||||||
|
repository.workspace = true
|
||||||
|
keywords.workspace = true
|
||||||
|
categories.workspace = true
|
||||||
|
readme = "README.md"
|
||||||
|
include = [
|
||||||
|
"**/*.rs",
|
||||||
|
"Cargo.toml",
|
||||||
|
"README.md",
|
||||||
|
"LICENSE-MIT",
|
||||||
|
"LICENSE-APACHE",
|
||||||
|
"CHANGELOG.md",
|
||||||
|
"docs",
|
||||||
|
]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
base64.workspace = true
|
||||||
|
chrono.workspace = true
|
||||||
|
clap.workspace = true
|
||||||
|
clap-verbosity-flag.workspace = true
|
||||||
|
config.workspace = true
|
||||||
|
dialoguer.workspace = true
|
||||||
|
env_logger.workspace = true
|
||||||
|
flate2.workspace = true
|
||||||
|
google-gmail1.workspace = true
|
||||||
|
hyper-rustls.workspace = true
|
||||||
|
indicatif.workspace = true
|
||||||
|
lazy-regex.workspace = true
|
||||||
|
log.workspace = true
|
||||||
|
serde.workspace = true
|
||||||
|
serde_json.workspace = true
|
||||||
|
thiserror.workspace = true
|
||||||
|
tokio.workspace = true
|
||||||
|
toml.workspace = true
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
assert_cmd.workspace = true
|
||||||
|
assert_fs.workspace = true
|
||||||
|
futures.workspace = true
|
||||||
|
httpmock.workspace = true
|
||||||
|
predicates.workspace = true
|
||||||
|
temp-env.workspace = true
|
||||||
|
tempfile.workspace = true
|
||||||
|
tokio-test.workspace = true
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "cull_gmail"
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "cull-gmail"
|
||||||
|
path = "src/cli/main.rs"
|
||||||
16
crates/cull-gmail/release-hook.sh
Executable file
16
crates/cull-gmail/release-hook.sh
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Build an updated README
|
||||||
|
cat ../../docs/readme/head.md > ../../README.md
|
||||||
|
# shellcheck disable=SC2129
|
||||||
|
cat ../../docs/main.md >> ../../README.md
|
||||||
|
cat ../../docs/lib.md >> ../../README.md
|
||||||
|
cat ../../docs/readme/tail.md >> ../../README.md
|
||||||
|
|
||||||
|
# Build Changelog
|
||||||
|
gen-changelog generate \
|
||||||
|
--display-summaries \
|
||||||
|
--name "CHANGELOG.md" \
|
||||||
|
--package "cull-gmail" \
|
||||||
|
--repository-dir "../.." \
|
||||||
|
--next-version "${NEW_VERSION:-${SEMVER}}"
|
||||||
7
crates/cull-gmail/release.toml
Normal file
7
crates/cull-gmail/release.toml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
pre-release-commit-message = "chore: Release cull-gmail v{{version}}"
|
||||||
|
tag-message = "{{tag_name}}"
|
||||||
|
tag-name = "cull-gmail-v{{version}}"
|
||||||
|
pre-release-hook = ["./release-hook.sh"]
|
||||||
|
pre-release-replacements = [
|
||||||
|
{ file = "../../docs/lib.md", search = "cull-gmail = \"\\d+\\.\\d+\\.\\d+\"", replace = "cull-gmail = \"{{version}}\"", exactly = 1 },
|
||||||
|
]
|
||||||
@@ -361,13 +361,13 @@ impl Rules {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use cull_gmail::{Rules, Retention, MessageAge};
|
/// use cull_gmail::{Rules, Retention, MessageAge, EolAction};
|
||||||
///
|
///
|
||||||
/// let mut rules = Rules::new();
|
/// let mut rules = Rules::new();
|
||||||
/// let retention = Retention::new(MessageAge::Days(30), false);
|
/// let retention = Retention::new(MessageAge::Days(30), false);
|
||||||
/// rules.add_rule(retention, Some("test"), false);
|
/// rules.add_rule(retention, Some("test"), false);
|
||||||
///
|
///
|
||||||
/// let label_map = rules.get_rules_by_label(EolAction::Trash);
|
/// let label_map = rules.get_rules_by_label_for_action(EolAction::Trash);
|
||||||
/// if let Some(rule) = label_map.get("test") {
|
/// if let Some(rule) = label_map.get("test") {
|
||||||
/// println!("Rule for 'test' label: {}", rule.describe());
|
/// println!("Rule for 'test' label: {}", rule.describe());
|
||||||
/// }
|
/// }
|
||||||
@@ -31,15 +31,17 @@ mod test_utils {
|
|||||||
|
|
||||||
// Get the path to the compiled binary - try multiple locations
|
// Get the path to the compiled binary - try multiple locations
|
||||||
let binary_path = if let Ok(manifest_dir) = std::env::var("CARGO_MANIFEST_DIR") {
|
let binary_path = if let Ok(manifest_dir) = std::env::var("CARGO_MANIFEST_DIR") {
|
||||||
// Running under cargo test - try release first, then debug
|
// Running under cargo test - binary is in workspace root target/
|
||||||
let release_binary = PathBuf::from(&manifest_dir)
|
// CARGO_MANIFEST_DIR = crates/cull-gmail, so go up two levels
|
||||||
|
let workspace_root = PathBuf::from(&manifest_dir).join("../..").canonicalize()?;
|
||||||
|
let release_binary = workspace_root
|
||||||
.join("target")
|
.join("target")
|
||||||
.join("release")
|
.join("release")
|
||||||
.join("cull-gmail");
|
.join("cull-gmail");
|
||||||
if release_binary.exists() {
|
if release_binary.exists() {
|
||||||
release_binary
|
release_binary
|
||||||
} else {
|
} else {
|
||||||
PathBuf::from(&manifest_dir)
|
workspace_root
|
||||||
.join("target")
|
.join("target")
|
||||||
.join("debug")
|
.join("debug")
|
||||||
.join("cull-gmail")
|
.join("cull-gmail")
|
||||||
13
release.toml
13
release.toml
@@ -1,14 +1,5 @@
|
|||||||
pre-release-replacements = [
|
|
||||||
{ file = "docs/lib.md", search = """cull-gmail = "\\d+.\\d+.\\d+"""", replace = "{{crate_name}} = \"{{version}}\"", exactly = 1 },
|
|
||||||
{ file = "PRLOG.md", search = "## \\[Unreleased\\]", replace = "## [{{version}}] - {{date}}", exactly = 1 },
|
|
||||||
{ file = "PRLOG.md", search = "\\[Unreleased\\]:", replace = "[{{version}}]:", exactly = 1 },
|
|
||||||
{ file = "PRLOG.md", search = "\\.\\.\\.HEAD", replace = "...{{tag_name}}", exactly = 1 },
|
|
||||||
]
|
|
||||||
pre-release-commit-message = "chore: Release {{crate_name}} v{{version}}"
|
|
||||||
tag-message = "{{tag_name}}"
|
|
||||||
tag-name = "{{prefix}}v{{version}}"
|
|
||||||
sign-tag = true
|
sign-tag = true
|
||||||
sign-commit = true
|
sign-commit = true
|
||||||
consolidate-commits = false
|
consolidate-commits = true
|
||||||
allow-branch = ["main"]
|
allow-branch = ["main"]
|
||||||
pre-release-hook = ["./release-hook.sh"]
|
pre-release-replacements = []
|
||||||
|
|||||||
Reference in New Issue
Block a user