Skip to content

Commit

Permalink
feat: Publish documentation to public distribution (#1232)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbelkins authored Dec 1, 2023
1 parent 05cd31f commit 96136a3
Show file tree
Hide file tree
Showing 15 changed files with 1,117 additions and 4 deletions.
84 changes: 84 additions & 0 deletions .github/workflows/generate-documentation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: Generate Documentation

on:
release:
types: [published]

permissions:
id-token: write

jobs:
generate-docs:
strategy:
matrix:
# Use strategy to split up the work into 32 jobs
job: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
runs-on: ubuntu-latest
container: swift:5.9-jammy
env:
IGNORE: none
outputs:
version: ${{ steps.set-version.outputs.version }}
steps:
- name: Checkout Sources
uses: actions/checkout@v4
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.CD_API_REFS_PUBLISH_ROLE_ARN }}
aws-region: us-east-1
- name: Install AWS CLI, jq, and native dependencies
run: |
DEBIAN_FRONTEND="noninteractive" apt-get update
apt-get -y install curl unzip openssl libssl-dev jq
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip && ./aws/install
- name: Extract version from GITHUB_REF
id: set-version
run: |
if [[ $GITHUB_REF == refs/tags/* ]]; then
echo "Tagged release"
# get last part of GITHUB_REF separated by /
VERSION=$(echo $GITHUB_REF | tr '/' '\n' | tail -1)
echo "Version: $VERSION"
echo "VERSION=$VERSION" >> "$GITHUB_ENV"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
else
echo "Error: runs on a tag only"
exit(1)
fi
- name: Generate docs
run: |
DOCS_BUCKET=${{ secrets.CD_API_REFS_BUCKET_NAME }} \
./scripts/generatedocc.sh "$VERSION" ${{ matrix.job }} ${{ strategy.job-total }} ${{ env.IGNORE }}
update-latest:
needs: generate-docs
runs-on: ubuntu-latest
steps:
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.CD_API_REFS_PUBLISH_ROLE_ARN }}
aws-region: us-east-1
- name: Install AWS CLI
run: |
# Need to install aws cli from latest since GH runner doesn't yet have
# cloudfront-keyvaluestore in the preinstalled version
DEBIAN_FRONTEND="noninteractive" sudo apt-get update
sudo apt-get -y install curl unzip
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip && sudo ./aws/install --update
- name: Update Cloudfront key value store
env:
VERSION: ${{ needs.generate-docs.outputs.version }}
run: |
export KVS_ETAG=`aws cloudfront-keyvaluestore describe-key-value-store \
--output text \
--query ETag \
--kvs-arn "${{ secrets.CD_CLOUDFRONT_KVS_ARN }}"`
aws cloudfront-keyvaluestore put-key \
--kvs-arn "${{ secrets.CD_CLOUDFRONT_KVS_ARN }}" \
--if-match "$KVS_ETAG" \
--key latest \
--value "$VERSION"
3 changes: 2 additions & 1 deletion AWSSDKSwiftCLI/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ let package = Package(
.product(name: "Logging", package: "swift-log"),
],
resources: [
.process("Resources/Package.Base.swift")
.process("Resources/Package.Base.swift"),
.process("Resources/DocIndex.Base.md")
],
swiftSettings: [
.unsafeFlags(["-package-description-version", "5.7"])
Expand Down
3 changes: 2 additions & 1 deletion AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/AWSSDKSwiftCLI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ struct AWSSDKSwiftCLI: ParsableCommand {
GeneratePackageManifestCommand.self,
PrepareReleaseCommand.self,
SyncClientRuntimeVersionCommand.self,
TestAWSSDKCommand.self
TestAWSSDKCommand.self,
GenerateDocIndexCommand.self
]
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

import ArgumentParser
import Foundation

// MARK: - Command

struct GenerateDocIndexCommand: ParsableCommand {
static var configuration = CommandConfiguration(
commandName: "generate-doc-index",
abstract: "Generates the documentation index for the AWSSDKforSwift documentation target."
)

@Argument(help: "The path to the aws-sdk-swift repository")
var repoPath: String

func run() throws {
try FileManager.default.changeWorkingDirectory(repoPath)
let contents = try generateDocIndexContents()
try saveDocIndex(contents)
}

// MARK: - Helpers

/// Returns the contents of the generated doc index.
/// This determines the versions of the dependencies and the list of services to include and then generates the doc index with those values.
///
/// - Returns: The contents of the generated doc index.
func generateDocIndexContents() throws -> String {
let services = try resolveServices()
log("Creating doc index contents...")
let contents = try DocIndexBuilder(services: services).build()
log("Successfully created doc index contents")
return contents
}

/// Saves the doc index file.
/// If no file exists, then this will create a new file. Otherwise, this will overwrite the existing file.
///
/// - Parameter contents: The contents of the doc index.
func saveDocIndex(_ contents: String) throws {
let docIndexFileName = "Sources/Core/AWSSDKForSwift/Documentation.docc/AWSSDKForSwift.md"
log("Saving doc index to \(docIndexFileName)...")
try contents.write(
toFile: docIndexFileName,
atomically: true,
encoding: .utf8
)
log("Successfully saved doc index to \(docIndexFileName)")
}

/// Returns the list of services to include in the doc index.
/// If an explicit list of services was provided by the command, then this returns the specified services.
/// Otherwise, this returns the list of services that exist within `Sources/Services`
///
/// - Returns: The list of services to include in the doc index
func resolveServices() throws -> [String] {
log("Resolving services...")
let resolvedServices: [String]
log("Using list of services that exist within Sources/Services")
resolvedServices = try FileManager.default.enabledServices()
log("Resolved list of services: \(resolvedServices.count)")
return resolvedServices
}
}
73 changes: 73 additions & 0 deletions AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Models/DocIndexBuilder.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

import Foundation
import PackageDescription

/// Builds the contents of the package manifest file.
struct DocIndexBuilder {
struct Service {
let name: String
}

let services: [String]
let baseDocIndexContents: () throws -> String

init(services: [String]) {
self.services = services
self.baseDocIndexContents = {
// Returns the contents of the base doc index stored in the bundle at `Resources/DocIndex.Base.md`
let basePackageName = "DocIndex.Base"

// Get the url for the base doc index that is stored in the bundle
guard let url = Bundle.module.url(forResource: basePackageName, withExtension: "md") else {
throw Error("Could not find \(basePackageName).md in bundle")
}

// Load the contents of the base doc index
let fileContents = try FileManager.default.loadContents(atPath: url.path)

// Convert the base doc index data to a string
guard let fileText = String(data: fileContents, encoding: .utf8) else {
throw Error("Failed to create string from contents of file \(basePackageName).swift")
}

return fileText
}
}

// MARK: - Build

/// Builds the contents of the package manifest file.
func build() throws -> String {
let contents = try [
baseDocIndexContents(),
"",
buildGeneratedContent()
]
return contents.joined(separator: "\n")
}

/// Builds all the generated package manifest content
private func buildGeneratedContent() -> String {
let contents = [
buildServiceIndex(),
""
]
return contents.joined(separator: .newline)
}

/// Returns a pragma mark comment to provide separation between the non-generated (base) and generated content
///
/// - Returns: A pragma mark comment to provide separation between the non-generated (base) and generated content
private func buildServiceIndex() -> String {
return services.map { service in
let urlService = service.lowercased(with: Locale(identifier: "en_US_POSIX"))
return "[\(service)](../../../../../swift/api/\(urlService)/latest)\n"
}.joined(separator: "\n")
}
}
11 changes: 11 additions & 0 deletions AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Resources/DocIndex.Base.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# ``AWSSDKForSwift``

A pure-Swift SDK for accessing all published AWS services.

## Overview

**The AWS SDK for Swift is currently in developer preview and is intended strictly for feedback purposes only. Do not use this SDK for production workloads. Refer to the SDK [stability guidelines](docs/stability.md) for more detail.**

This SDK is open-source. Code is available on Github [here](https://github.com/awslabs/aws-sdk-swift).

## Service Documentation
12 changes: 12 additions & 0 deletions AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Resources/Package.Base.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ let package = Package(
.library(name: "AWSClientRuntime", targets: ["AWSClientRuntime"])
],
targets: [
.target(
name: "AWSSDKForSwift",
path: "Sources/Core/AWSSDKForSwift",
exclude: ["Documentation.docc/AWSSDKForSwift.md"]
),
.target(
name: "AWSClientRuntime",
dependencies: [.crt, .clientRuntime],
Expand All @@ -53,6 +58,7 @@ let package = Package(
func addDependencies(clientRuntimeVersion: Version, crtVersion: Version) {
addClientRuntimeDependency(clientRuntimeVersion)
addCRTDependency(crtVersion)
addDoccDependency()
}

func addClientRuntimeDependency(_ version: Version) {
Expand Down Expand Up @@ -83,6 +89,12 @@ func addCRTDependency(_ version: Version) {
]
}

func addDoccDependency() {
package.dependencies += [
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0")
]
}

// MARK: - Services

func addServiceTarget(_ name: String) {
Expand Down
12 changes: 12 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ let package = Package(
.library(name: "AWSClientRuntime", targets: ["AWSClientRuntime"])
],
targets: [
.target(
name: "AWSSDKForSwift",
path: "Sources/Core/AWSSDKForSwift",
exclude: ["Documentation.docc/AWSSDKForSwift.md"]
),
.target(
name: "AWSClientRuntime",
dependencies: [.crt, .clientRuntime],
Expand All @@ -53,6 +58,7 @@ let package = Package(
func addDependencies(clientRuntimeVersion: Version, crtVersion: Version) {
addClientRuntimeDependency(clientRuntimeVersion)
addCRTDependency(crtVersion)
addDoccDependency()
}

func addClientRuntimeDependency(_ version: Version) {
Expand Down Expand Up @@ -83,6 +89,12 @@ func addCRTDependency(_ version: Version) {
]
}

func addDoccDependency() {
package.dependencies += [
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0")
]
}

// MARK: - Services

func addServiceTarget(_ name: String) {
Expand Down
8 changes: 8 additions & 0 deletions Sources/Core/AWSSDKForSwift/AWSSDKForSwift.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

// Empty source file to satisfy the minimum requirements for a valid target
Loading

0 comments on commit 96136a3

Please sign in to comment.