Unverified Commit 52c1174a authored by John DiSanti's avatar John DiSanti Committed by GitHub
Browse files

Decouple `aws-sdk-rust` release from `smithy-rs` release (#1495)

* Remove smoketest/fullsdk model classifications
* Generate full SDK for CI using models in aws-sdk-rust
* Move the changelog renderer out of `sdk-lints` and add changelog splitter
* Save revision information into split off SDK changelog
* Replace common git impl with `sdk-sync`'s impl
* Filter SDK changelog entries on changelog render
* Add smithy-rs release workflow
* Add initial next SDK changelog
* Update `sdk-sync` to understand new models location
parent ae2a74b5
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -27,11 +27,17 @@ jobs:
        actions:
        - action: generate-aws-sdk
        - action: generate-aws-sdk-smoketest
        - action: generate-smithy-rs-runtime-bundle
        - action: generate-smithy-rs-release
    steps:
    - uses: actions/checkout@v3
      with:
        path: smithy-rs
    # The models from aws-sdk-rust are needed to generate the full SDK for CI
    - uses: actions/checkout@v3
      with:
        repository: awslabs/aws-sdk-rust
        path: aws-sdk-rust
    # The examples from aws-doc-sdk-examples are needed to see if smithy-rs changes break examples
    - uses: actions/checkout@v3
      with:
        repository: awsdocs/aws-doc-sdk-examples
+83 −0
Original line number Diff line number Diff line
/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0
 */

// This script is used by the release.yml GitHub Actions workflow to idempotently
// create a tagged GitHub release from the generated release manifest file.

const assert = require("assert");
const fs = require("fs");

const smithy_rs_repo = {
    owner: "awslabs",
    repo: "smithy-rs",
};

async function getExistingRelease(github, tag) {
    try {
        const response = await github.rest.repos.getReleaseByTag({ ...smithy_rs_repo, tag });
        return { name: response.data.name, body: response.data.body };
    } catch (error) {
        if (error.status === 404) {
            console.info(`No existing release found with tag '${tag}'`);
            return null;
        }
        throw error;
    }
}

function loadReleaseManifest(path) {
    const releaseManifest = JSON.parse(fs.readFileSync(path));
    console.info("Release manifest: ", releaseManifest);
    assert(releaseManifest.tagName !== undefined, "release manifest must have a `tagName` field");
    assert(releaseManifest.name !== undefined, "release manifest must have a `name` field");
    assert(releaseManifest.body !== undefined, "release manifest must have a `body` field");
    assert(releaseManifest.prerelease !== undefined, "release manifest must have a `prerelease` field");
    return releaseManifest;
}

module.exports = async ({
    // GitHub API (Octokit)
    github,
    // Boolean indicating if this is a dry-run release or not
    isDryRun,
    // Release manifest file path
    releaseManifestPath,
}) => {
    assert(github !== undefined, "The `github` argument is required");
    assert(isDryRun !== undefined, "The `isDryRun` argument is required");
    assert(releaseManifestPath !== undefined, "The `releaseManifestPath` argument is required");

    console.info(`Starting GitHub release creation with isDryRun: ${isDryRun}, and releaseManifestPath: '${releaseManifestPath}'`);

    // Load the release manifest generated by the `changelogger` tool during build
    const releaseManifest = loadReleaseManifest(releaseManifestPath);

    // Idempotency check: Look up an existing GitHub release for the tag in the release manifest
    const existingRelease = await getExistingRelease(github, releaseManifest.tagName);
    if (existingRelease) {
        console.info(`Found an existing release with tag '${releaseManifest.tagName}': `, existingRelease);
        if (existingRelease.name !== releaseManifest.name || existingRelease.body !== releaseManifest.body) {
            throw Error("FATAL: Existing release does not match the release manifest!");
        } else {
            console.info("SUCCESS: Existing release matches details in the release manifest. No work needs to be done!");
        }
    } else {
        // Explicitly comparing against `false` to avoid accidental publish in the event that
        // the `isDryRun` argument wasn't passed in correctly from the GitHub Actions workflow.
        if (isDryRun === false) {
            console.info("Not a dry-run; creating a new release...");
            const response = await github.rest.repos.createRelease({
                ...smithy_rs_repo,
                tag_name: releaseManifest.tagName,
                name: releaseManifest.name,
                body: releaseManifest.body,
                prerelease: releaseManifest.prerelease,
            });
            console.info(`SUCCESS: Created release with ID: ${response.data.id}, URL: ${response.data.html_url} `);
        } else {
            console.info("SUCCESS: Exiting early since this is a dry-run release.");
        }
    }
};
+95 −0
Original line number Diff line number Diff line
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

# This workflow performs a release of smithy-rs. It is manually
# kicked off via GitHub Actions workflow dispatch.

# Allow only one release to run at a time
concurrency:
  group: release-smithy-rs
  cancel-in-progress: true

env:
  rust_version: 1.58.1

name: Release smithy-rs
on:
  workflow_dispatch:
    inputs:
      dry_run:
        description: Dry runs will only produce release artifacts, but will not cut a release tag in GitHub nor publish to crates.io
        required: true
        type: boolean
        default: true

jobs:
  release-ci:
    name: Prerelease checks
    uses: ./.github/workflows/ci.yml

  release:
    name: Release
    needs:
    - release-ci
    runs-on: ubuntu-latest
    steps:
    - name: Install Rust
      uses: actions-rs/toolchain@v1
      with:
        toolchain: ${{ env.rust_version }}
        default: true
    - name: Checkout smithy-rs
      uses: actions/checkout@v3
      with:
        path: smithy-rs
        token: ${{ secrets.RELEASE_AUTOMATION_BOT_PAT }}
    - name: Generate release artifacts
      uses: ./smithy-rs/.github/actions/docker-build
      with:
        action: generate-smithy-rs-release
    - name: Download all artifacts
      uses: ./smithy-rs/.github/actions/download-all-artifacts
    - name: Push smithy-rs changes
      shell: bash
      working-directory: smithy-rs-release/smithy-rs
      run: |
        if [[ "${{ inputs.dry_run }}" == "true" ]]; then
          echo "Pushing a preview of the release to the smithy-rs-release-preview branch"
          git push --force origin HEAD:smithy-rs-release-preview
        else
          echo "Pushing release commits..."
          git push origin
        fi
    - name: Tag release
      uses: actions/github-script@v6
      with:
        github-token: ${{ secrets.RELEASE_AUTOMATION_BOT_PAT }}
        script: |
          const createReleaseScript = require("./smithy-rs/.github/workflows/release-scripts/create-release.js");
          await createReleaseScript({
            github,
            isDryRun: ${{ inputs.dry_run }},
            releaseManifestPath: "smithy-rs-release/smithy-rs-release-manifest.json"
          });
    - name: Publish to crates.io
      shell: bash
      working-directory: smithy-rs-release/crates-to-publish
      env:
        RELEASE_AUTOMATION_BOT_CRATESIO_TOKEN: ${{ secrets.RELEASE_AUTOMATION_BOT_CRATESIO_TOKEN }}
      run: |
        cargo login -- "${RELEASE_AUTOMATION_BOT_CRATESIO_TOKEN}"
        cargo install --path ../smithy-rs/tools/publisher
        # Verify the publisher tool installed successfully
        publisher --version

        if [[ "${{ inputs.dry_run }}" == "true" ]]; then
          if [[ ! -f aws-smithy-types/Cargo.toml ]]; then
            echo "Crates to publish not found!"
            exit 1
          fi
          # The following owner list command fails without a valid crates.io auth token
          echo "Checking cargo auth token..."
          cargo owner --list aws-smithy-types
        else
          publisher publish --location .
        fi

aws/SDK_CHANGELOG.md

deleted100644 → 0
+0 −1107

File deleted.

Preview size limit exceeded, changes collapsed.

+49 −0
Original line number Diff line number Diff line
# This file will be used by automation when cutting a release of the SDK
# to include code generator change log entries into the release notes.
# This is an auto-generated file. Do not edit.

{
  "smithy-rs": [],
  "aws-sdk-rust": [
    {
      "message": "Add method `ByteStream::into_async_read`. This makes it easy to convert `ByteStream`s into a struct implementing `tokio:io::AsyncRead`. Available on **crate feature** `rt-tokio` only.",
      "meta": {
        "bug": false,
        "breaking": false,
        "tada": true
      },
      "author": "Velfi",
      "references": [
        "smithy-rs#1390"
      ],
      "since-commit": "1d81b4f717c1f4416cd3e9680704624ce07c57c4"
    },
    {
      "message": "Switch to [RustCrypto](https://github.com/RustCrypto)'s implementation of MD5.",
      "meta": {
        "bug": false,
        "breaking": false,
        "tada": false
      },
      "author": "petrosagg",
      "references": [
        "smithy-rs#1404"
      ],
      "since-commit": "1d81b4f717c1f4416cd3e9680704624ce07c57c4"
    },
    {
      "message": "Add support for `credential_process` in AWS configs for fetching credentials from an external process.",
      "meta": {
        "bug": false,
        "breaking": false,
        "tada": true
      },
      "author": "jszwedko",
      "references": [
        "smithy-rs#1356"
      ],
      "since-commit": "1d81b4f717c1f4416cd3e9680704624ce07c57c4"
    }
  ],
  "aws-sdk-model": []
}
Loading