From 59023606b889379bc856b5145f699d150bc76057 Mon Sep 17 00:00:00 2001 From: Alon Gubkin Date: Tue, 7 Apr 2026 18:54:20 +0300 Subject: [PATCH 1/2] ci: automate releases with release-plz Replace the manual release workflow with release-plz, which automatically opens release PRs with version bumps and changelog updates, then tags, creates GitHub Releases, and publishes to crates.io on merge. Closes ALIEN-15 Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/release-plz.yml | 40 +++++++++++++++++++++++++++ .github/workflows/release.yml | 23 ---------------- cliff.toml | 46 +++++++++++++++++++++++++++++++ release-plz.toml | 5 ++++ 4 files changed, 91 insertions(+), 23 deletions(-) create mode 100644 .github/workflows/release-plz.yml delete mode 100644 .github/workflows/release.yml create mode 100644 cliff.toml create mode 100644 release-plz.toml diff --git a/.github/workflows/release-plz.yml b/.github/workflows/release-plz.yml new file mode 100644 index 0000000..de87b97 --- /dev/null +++ b/.github/workflows/release-plz.yml @@ -0,0 +1,40 @@ +name: Release-plz + +permissions: + pull-requests: write + contents: write + +on: + push: + branches: + - main + +jobs: + release-plz-release-pr: + name: Release PR + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: dtolnay/rust-toolchain@stable + - uses: MarcoIeni/release-plz-action@v0.5 + with: + command: release-pr + env: + GITHUB_TOKEN: ${{ secrets.RELEASE_PLZ_TOKEN }} + + release-plz-release: + name: Release + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: dtolnay/rust-toolchain@stable + - uses: MarcoIeni/release-plz-action@v0.5 + with: + command: release + env: + GITHUB_TOKEN: ${{ secrets.RELEASE_PLZ_TOKEN }} + CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_IO_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 6070d20..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Release - -on: - release: - types: [published] - -permissions: - contents: read - -env: - CARGO_TERM_COLOR: always - -jobs: - publish: - name: Publish to crates.io - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 - - run: cargo publish - env: - CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_IO_TOKEN }} diff --git a/cliff.toml b/cliff.toml new file mode 100644 index 0000000..efbfd6e --- /dev/null +++ b/cliff.toml @@ -0,0 +1,46 @@ +[changelog] +header = """ +# Changelog + +All notable changes to this project will be documented in this file. + +""" +body = """ +{%- macro remote_url() -%} + https://github.com/alienplatform/dockdash +{%- endmacro -%} + +{% if version -%} + ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }} +{% else -%} + ## [Unreleased] +{% endif -%} + +{% for group, commits in commits | group_by(attribute="group") %} + ### {{ group | upper_first }} + {% for commit in commits %} + - {% if commit.breaking %}**BREAKING** {% endif %}\ + {{ commit.message | upper_first }} \ + ([{{ commit.id | truncate(length=7, end="") }}]({{ self::remote_url() }}/commit/{{ commit.id }}))\ + {% endfor %} +{% endfor %} +""" +trim = true + +[git] +conventional_commits = true +filter_unconventional = true +split_commits = false +commit_parsers = [ + { message = "^feat", group = "Features" }, + { message = "^fix", group = "Bug Fixes" }, + { message = "^doc", group = "Documentation" }, + { message = "^perf", group = "Performance" }, + { message = "^refactor", group = "Refactoring" }, + { message = "^style", group = "Styling" }, + { message = "^test", group = "Testing" }, + { message = "^chore\\(release\\)", skip = true }, + { message = "^chore", group = "Miscellaneous" }, +] +filter_commits = false +tag_pattern = "v[0-9].*" diff --git a/release-plz.toml b/release-plz.toml new file mode 100644 index 0000000..7408c68 --- /dev/null +++ b/release-plz.toml @@ -0,0 +1,5 @@ +[workspace] +changelog_config = "cliff.toml" +changelog_update = true +git_tag_name = "v{{ version }}" +pr_name = "chore: release v{{ version }}" From 1ac0d2be215b47fb764a04591d0c9af72832fbaf Mon Sep 17 00:00:00 2001 From: Alon Gubkin Date: Sun, 12 Apr 2026 22:49:10 +0300 Subject: [PATCH 2/2] Add protocol field to PullAndExtractOptions and ImageBuilder Allows callers to specify HTTP vs HTTPS when pulling images. Defaults to HTTPS. Needed for pulling from localhost registries (embedded local OCI registry in alien-manager). ALIEN-16 Co-Authored-By: Claude Opus 4.6 (1M context) --- src/image.rs | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/image.rs b/src/image.rs index 5a9a78b..18165e5 100644 --- a/src/image.rs +++ b/src/image.rs @@ -202,6 +202,8 @@ pub struct PullAndExtractOptions { pub blob_cache: Option, /// Optional authentication for the registry pub auth: Option, + /// Protocol to use (Http or Https). Defaults to Https. + pub protocol: ClientProtocol, } /// Represents a built OCI image stored as an OCI layout tarball. @@ -219,7 +221,21 @@ pub struct Image { impl Image { /// Returns a builder to construct an `Image`. pub fn builder() -> ImageBuilder { - ImageBuilder::default() + ImageBuilder { + base_image_ref: None, + platform_os: None, + platform_arch: None, + layers: Vec::new(), + entrypoint: None, + cmd: None, + working_dir: None, + output_path: None, + blob_cache: None, + output_image_name_and_tag: None, + pull_policy: None, + auth: None, + protocol: ClientProtocol::Https, + } } /// Loads an existing OCI tarball from disk. @@ -288,7 +304,8 @@ impl Image { // Build the image (pulls from registry, uses cache) let mut builder = Image::builder() .from(image_ref) - .pull_policy(options.pull_policy); + .pull_policy(options.pull_policy) + .protocol(options.protocol); match (options.platform_os, options.platform_arch) { (Some(os), Some(arch)) => { @@ -919,6 +936,7 @@ pub struct ImageBuilder { output_image_name_and_tag: Option, pull_policy: Option, auth: Option, + protocol: ClientProtocol, } impl ImageBuilder { @@ -989,6 +1007,12 @@ impl ImageBuilder { /// Sets the authentication for pulling the base image. /// If not set, authentication is determined from environment variables (DOCKER_USERNAME/DOCKER_PASSWORD). + /// Sets the protocol (Http or Https) for registry communication. + pub fn protocol(mut self, protocol: ClientProtocol) -> Self { + self.protocol = protocol; + self + } + pub fn auth(mut self, auth: RegistryAuth) -> Self { self.auth = Some(auth); self @@ -1051,7 +1075,10 @@ impl ImageBuilder { } }; - let mut client_cfg = ClientConfig::default(); + let mut client_cfg = ClientConfig { + protocol: self.protocol.clone(), + ..Default::default() + }; if let (Some(os_filter_val), Some(arch_filter_val)) = (&self.platform_os, &self.platform_arch)