diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml new file mode 100644 index 0000000..11a5157 --- /dev/null +++ b/.github/workflows/pull_request.yml @@ -0,0 +1,16 @@ +name: PR + +on: + pull_request: + types: [opened, reopened, synchronize] + +jobs: + soundness: + name: Soundness + uses: apple/swift-nio/.github/workflows/soundness.yml@main + with: + api_breakage_check_container_image: "swift:6.0-noble" + api_breakage_check_enabled: false + docs_check_container_image: "swift:6.0-noble" + license_header_check_project_name: "SwiftContainerPlugin" + shell_check_container_image: "swift:6.0-noble" diff --git a/.licenseignore b/.licenseignore new file mode 100644 index 0000000..a231d97 --- /dev/null +++ b/.licenseignore @@ -0,0 +1,28 @@ +**/*.docc/* +**/*.md +**/.gitignore +**/Package.resolved +**/Package.swift +**/README.md +.dockerignore +.github/* +.gitignore +.licenseignore +.mailmap +.spi.yml +.swift-format +.swiftformatignore +CODE_OF_CONDUCT.md +CONTRIBUTING.md +CONTRIBUTORS.txt +LICENSE.txt +NOTICE.txt +Package.resolved +Package.swift +README.md +SECURITY.md +Tests/ContainerRegistryTests/Resources/* +Vendor/* +docker-compose.yaml +docker/* +scripts/* diff --git a/.spi.yml b/.spi.yml new file mode 100644 index 0000000..f1587e6 --- /dev/null +++ b/.spi.yml @@ -0,0 +1,6 @@ +version: 1 +builder: + configs: + - documentation_targets: + - ContainerRegistry + - ContainerImageBuilderPlugin diff --git a/.swiftformatignore b/.swiftformatignore new file mode 100644 index 0000000..e5a51f9 --- /dev/null +++ b/.swiftformatignore @@ -0,0 +1 @@ +Vendor/* diff --git a/Sources/ContainerImageBuilderPluginDocumentation/Documentation.docc/ContainerImageBuilderPlugin.md b/Sources/ContainerImageBuilderPluginDocumentation/Documentation.docc/ContainerImageBuilderPlugin.md index 22a5e50..84312d1 100644 --- a/Sources/ContainerImageBuilderPluginDocumentation/Documentation.docc/ContainerImageBuilderPlugin.md +++ b/Sources/ContainerImageBuilderPluginDocumentation/Documentation.docc/ContainerImageBuilderPlugin.md @@ -20,7 +20,7 @@ The plugin does not require a container runtime to be installed locally in order Try one of the [Examples](../../../Examples) -## Install a Swift SDK for cross-compilation on macOS +### Install a Swift SDK for cross-compilation on macOS If you are running on macOS, you can use a [Swift SDK](https://github.com/apple/swift-evolution/blob/main/proposals/0387-cross-compilation-destinations.md) to cross-compile your server executable for Linux. Either: @@ -36,7 +36,7 @@ swift-6.0.1-RELEASE_static-linux-0.0.1 > Note: To use the Static Linux SDK on macOS, you must [install the open source Swift toolchain from swift.org](https://www.swift.org/documentation/articles/static-linux-getting-started.html#installing-the-sdk) -## Add the plugin to your project +### Add the plugin to your project Swift Container Plugin is distributed as a Swift Package Manager package. Use the `swift package` command to add it to your project: @@ -59,7 +59,7 @@ Check that `ContainerImageBuilder` is now available in Swift Package Manager: ‘build-container-image’ (plugin ‘ContainerImageBuilder’ in package ‘swift-container-plugin) ``` -## Add your registry credentials to .netrc +### Add your registry credentials to .netrc Many registries require authentication in order to push images, or even pull them. The plugin can read your registry credentials from a `.netrc` file in your home directory. You can add a netrc record for each registry you need to use: @@ -69,7 +69,7 @@ machine registry.example.com password mypassword ``` -## Build and package your service +### Build and package your service `build-container-image` takes care of building your service, packaging it in a container image and uploading it to a container registry, all in one command: @@ -110,7 +110,7 @@ registry.example.com/myservice@sha256:a3f75d0932d052dd9d448a1c9040b16f9f2c2ed919 When it finishes, ContainerImageBuilder prints a reference identifying the new image. Any standard container runtime can use the reference to pull and run your service. -## Run your service +### Run your service For example, you could use `podman` to run the service locally, making it available on port 8080: diff --git a/scripts/check-for-broken-symlinks.sh b/scripts/check-for-broken-symlinks.sh deleted file mode 100644 index 195221e..0000000 --- a/scripts/check-for-broken-symlinks.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash -##===----------------------------------------------------------------------===## -## -## This source file is part of the SwiftContainerPlugin open source project -## -## Copyright (c) 2024 Apple Inc. and the SwiftContainerPlugin project authors -## Licensed under Apache License v2.0 -## -## See LICENSE.txt for license information -## See CONTRIBUTORS.txt for the list of SwiftContainerPlugin project authors -## -## SPDX-License-Identifier: Apache-2.0 -## -##===----------------------------------------------------------------------===## -##===----------------------------------------------------------------------===## -## -## This source file is part of the SwiftOpenAPIGenerator open source project -## -## Copyright (c) 2023 Apple Inc. and the SwiftOpenAPIGenerator project authors -## Licensed under Apache License v2.0 -## -## See LICENSE.txt for license information -## See CONTRIBUTORS.txt for the list of SwiftOpenAPIGenerator project authors -## -## SPDX-License-Identifier: Apache-2.0 -## -##===----------------------------------------------------------------------===## -set -euo pipefail - -log() { printf -- "** %s\n" "$*" >&2; } -error() { printf -- "** ERROR: %s\n" "$*" >&2; } -fatal() { error "$@"; exit 1; } - -CURRENT_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -REPO_ROOT="$(git -C "${CURRENT_SCRIPT_DIR}" rev-parse --show-toplevel)" - -log "Checking for broken symlinks..." -NUM_BROKEN_SYMLINKS=0 -while read -r -d '' file; do - if ! test -e "${REPO_ROOT}/${file}"; then - error "Broken symlink: ${file}" - ((NUM_BROKEN_SYMLINKS++)) - fi -done < <(git -C "${REPO_ROOT}" ls-files -z) - -if [ "${NUM_BROKEN_SYMLINKS}" -gt 0 ]; then - fatal "❌ Found ${NUM_BROKEN_SYMLINKS} symlinks." -fi - -log "✅ Found 0 symlinks." diff --git a/scripts/check-for-docc-warnings.sh b/scripts/check-for-docc-warnings.sh deleted file mode 100644 index 6d59b84..0000000 --- a/scripts/check-for-docc-warnings.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env bash -##===----------------------------------------------------------------------===## -## -## This source file is part of the SwiftContainerPlugin open source project -## -## Copyright (c) 2024 Apple Inc. and the SwiftContainerPlugin project authors -## Licensed under Apache License v2.0 -## -## See LICENSE.txt for license information -## See CONTRIBUTORS.txt for the list of SwiftContainerPlugin project authors -## -## SPDX-License-Identifier: Apache-2.0 -## -##===----------------------------------------------------------------------===## -##===----------------------------------------------------------------------===## -## -## This source file is part of the SwiftOpenAPIGenerator open source project -## -## Copyright (c) 2023 Apple Inc. and the SwiftOpenAPIGenerator project authors -## Licensed under Apache License v2.0 -## -## See LICENSE.txt for license information -## See CONTRIBUTORS.txt for the list of SwiftOpenAPIGenerator project authors -## -## SPDX-License-Identifier: Apache-2.0 -## -##===----------------------------------------------------------------------===## - -set -euo pipefail - -log() { printf -- "** %s\n" "$*" >&2; } -error() { printf -- "** ERROR: %s\n" "$*" >&2; } -fatal() { error "$@"; exit 1; } - -log "Checking required environment variables..." -test -n "${DOCC_TARGET:-}" || fatal "DOCC_TARGET unset" - -CURRENT_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -REPO_ROOT="$(git -C "${CURRENT_SCRIPT_DIR}" rev-parse --show-toplevel)" - -swift package --package-path "${REPO_ROOT}" plugin generate-documentation \ - --product "${DOCC_TARGET}" \ - --analyze \ - --level detailed \ - --warnings-as-errors \ - && DOCC_PLUGIN_RC=$? || DOCC_PLUGIN_RC=$? - -if [ "${DOCC_PLUGIN_RC}" -ne 0 ]; then - fatal "❌ Generating documentation produced warnings and/or errors." - exit "${DOCC_PLUGIN_RC}" -fi - -log "✅ Generated documentation with no warnings." diff --git a/scripts/check-for-unacceptable-language.sh b/scripts/check-for-unacceptable-language.sh deleted file mode 100644 index 7eb6ce1..0000000 --- a/scripts/check-for-unacceptable-language.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash -##===----------------------------------------------------------------------===## -## -## This source file is part of the SwiftContainerPlugin open source project -## -## Copyright (c) 2024 Apple Inc. and the SwiftContainerPlugin project authors -## Licensed under Apache License v2.0 -## -## See LICENSE.txt for license information -## See CONTRIBUTORS.txt for the list of SwiftContainerPlugin project authors -## -## SPDX-License-Identifier: Apache-2.0 -## -##===----------------------------------------------------------------------===## -##===----------------------------------------------------------------------===## -## -## This source file is part of the SwiftOpenAPIGenerator open source project -## -## Copyright (c) 2023 Apple Inc. and the SwiftOpenAPIGenerator project authors -## Licensed under Apache License v2.0 -## -## See LICENSE.txt for license information -## See CONTRIBUTORS.txt for the list of SwiftOpenAPIGenerator project authors -## -## SPDX-License-Identifier: Apache-2.0 -## -##===----------------------------------------------------------------------===## -set -euo pipefail - -log() { printf -- "** %s\n" "$*" >&2; } -error() { printf -- "** ERROR: %s\n" "$*" >&2; } -fatal() { error "$@"; exit 1; } - -CURRENT_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -REPO_ROOT="$(git -C "${CURRENT_SCRIPT_DIR}" rev-parse --show-toplevel)" -UNACCEPTABLE_LANGUAGE_PATTERNS_PATH="${CURRENT_SCRIPT_DIR}/unacceptable-language.txt" - -log "Checking for unacceptable language..." -PATHS_WITH_UNACCEPTABLE_LANGUAGE=$(git -C "${REPO_ROOT}" grep \ - -l -F -w \ - -f "${UNACCEPTABLE_LANGUAGE_PATTERNS_PATH}" \ - -- \ - ":(exclude)${UNACCEPTABLE_LANGUAGE_PATTERNS_PATH}" \ -) || true | /usr/bin/paste -s -d " " - - -if [ -n "${PATHS_WITH_UNACCEPTABLE_LANGUAGE}" ]; then - fatal "❌ Found unacceptable language in files: ${PATHS_WITH_UNACCEPTABLE_LANGUAGE}." -fi - -log "✅ Found no unacceptable language." diff --git a/scripts/check-license-headers.sh b/scripts/check-license-headers.sh deleted file mode 100644 index fa1c2b7..0000000 --- a/scripts/check-license-headers.sh +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/env bash -##===----------------------------------------------------------------------===## -## -## This source file is part of the SwiftContainerPlugin open source project -## -## Copyright (c) 2024 Apple Inc. and the SwiftContainerPlugin project authors -## Licensed under Apache License v2.0 -## -## See LICENSE.txt for license information -## See CONTRIBUTORS.txt for the list of SwiftContainerPlugin project authors -## -## SPDX-License-Identifier: Apache-2.0 -## -##===----------------------------------------------------------------------===## -##===----------------------------------------------------------------------===## -## -## This source file is part of the SwiftOpenAPIGenerator open source project -## -## Copyright (c) 2023 Apple Inc. and the SwiftOpenAPIGenerator project authors -## Licensed under Apache License v2.0 -## -## See LICENSE.txt for license information -## See CONTRIBUTORS.txt for the list of SwiftOpenAPIGenerator project authors -## -## SPDX-License-Identifier: Apache-2.0 -## -##===----------------------------------------------------------------------===## -set -euo pipefail - -log() { printf -- "** %s\n" "$*" >&2; } -error() { printf -- "** ERROR: %s\n" "$*" >&2; } -fatal() { error "$@"; exit 1; } - -CURRENT_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -REPO_ROOT="$(git -C "${CURRENT_SCRIPT_DIR}" rev-parse --show-toplevel)" - -EXPECTED_FILE_HEADER_TEMPLATE="@@===----------------------------------------------------------------------===@@ -@@ -@@ This source file is part of the SwiftContainerPlugin open source project -@@ -@@ Copyright (c) YEARS Apple Inc. and the SwiftContainerPlugin project authors -@@ Licensed under Apache License v2.0 -@@ -@@ See LICENSE.txt for license information -@@ See CONTRIBUTORS.txt for the list of SwiftContainerPlugin project authors -@@ -@@ SPDX-License-Identifier: Apache-2.0 -@@ -@@===----------------------------------------------------------------------===@@" - -PATHS_WITH_MISSING_LICENSE=( ) - -read -ra PATHS_TO_CHECK_FOR_LICENSE <<< "$( \ - git -C "${REPO_ROOT}" ls-files -z \ - ":(exclude).gitignore" \ - ":(exclude).spi.yml" \ - ":(exclude).swift-format" \ - ":(exclude).github/*" \ - ":(exclude)CODE_OF_CONDUCT.md" \ - ":(exclude)CONTRIBUTING.md" \ - ":(exclude)CONTRIBUTORS.txt" \ - ":(exclude)LICENSE.txt" \ - ":(exclude)NOTICE.txt" \ - ":(exclude)Package.swift" \ - ":(exclude)Package.resolved" \ - ":(exclude)README.md" \ - ":(exclude)SECURITY.md" \ - ":(exclude)scripts/unacceptable-language.txt" \ - ":(exclude)Sources/ContainerRegistry/openapi/*" \ - ":(exclude)Tests/ContainerRegistryTests/Resources/*" \ - ":(exclude)Vendor/*" \ - ":(exclude)docker/*" \ - ":(exclude)**/*.docc/*" \ - ":(exclude)**/.gitignore" \ - ":(exclude)**/Package.swift" \ - ":(exclude)**/Package.resolved" \ - ":(exclude)**/README.md" \ - ":(exclude)**/docker-compose.yaml" \ - ":(exclude)**/docker/*" \ - ":(exclude)**/.dockerignore" \ - | xargs -0 \ -)" - -for FILE_PATH in "${PATHS_TO_CHECK_FOR_LICENSE[@]}"; do - FILE_BASENAME=$(basename -- "${FILE_PATH}") - FILE_EXTENSION="${FILE_BASENAME##*.}" - - case "${FILE_EXTENSION}" in - swift) EXPECTED_FILE_HEADER=$(sed -e 's|@@|//|g' <<<"${EXPECTED_FILE_HEADER_TEMPLATE}") ;; - yml) EXPECTED_FILE_HEADER=$(sed -e 's|@@|##|g' <<<"${EXPECTED_FILE_HEADER_TEMPLATE}") ;; - sh) EXPECTED_FILE_HEADER=$(cat <(echo '#!/usr/bin/env bash') <(sed -e 's|@@|##|g' <<<"${EXPECTED_FILE_HEADER_TEMPLATE}")) ;; - *) fatal "Unsupported file extension for file (exclude or update this script): ${FILE_PATH}" ;; - esac - EXPECTED_FILE_HEADER_LINECOUNT=$(wc -l <<<"${EXPECTED_FILE_HEADER}") - - FILE_HEADER=$(head -n "${EXPECTED_FILE_HEADER_LINECOUNT}" "${FILE_PATH}") - NORMALIZED_FILE_HEADER=$( - echo "${FILE_HEADER}" \ - | sed -e 's/202[4]-202[4]/YEARS/' -e 's/202[4]/YEARS/' \ - ) - - if ! diff -u \ - --label "Expected header" <(echo "${EXPECTED_FILE_HEADER}") \ - --label "${FILE_PATH}" <(echo "${NORMALIZED_FILE_HEADER}") - then - PATHS_WITH_MISSING_LICENSE+=("${FILE_PATH} ") - fi -done - -if [ "${#PATHS_WITH_MISSING_LICENSE[@]}" -gt 0 ]; then - fatal "❌ Found missing license header in files: ${PATHS_WITH_MISSING_LICENSE[*]}." -fi - -log "✅ Found no files with missing license header." diff --git a/scripts/run-swift-format.sh b/scripts/run-swift-format.sh deleted file mode 100755 index 760ccaf..0000000 --- a/scripts/run-swift-format.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env bash -##===----------------------------------------------------------------------===## -## -## This source file is part of the SwiftContainerPlugin open source project -## -## Copyright (c) 2024 Apple Inc. and the SwiftContainerPlugin project authors -## Licensed under Apache License v2.0 -## -## See LICENSE.txt for license information -## See CONTRIBUTORS.txt for the list of SwiftContainerPlugin project authors -## -## SPDX-License-Identifier: Apache-2.0 -## -##===----------------------------------------------------------------------===## -##===----------------------------------------------------------------------===## -## -## This source file is part of the SwiftOpenAPIGenerator open source project -## -## Copyright (c) 2023 Apple Inc. and the SwiftOpenAPIGenerator project authors -## Licensed under Apache License v2.0 -## -## See LICENSE.txt for license information -## See CONTRIBUTORS.txt for the list of SwiftOpenAPIGenerator project authors -## -## SPDX-License-Identifier: Apache-2.0 -## -##===----------------------------------------------------------------------===## -set -euo pipefail - -log() { printf -- "** %s\n" "$*" >&2; } -error() { printf -- "** ERROR: %s\n" "$*" >&2; } -fatal() { error "$@"; exit 1; } - -CURRENT_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -REPO_ROOT="$(git -C "${CURRENT_SCRIPT_DIR}" rev-parse --show-toplevel)" - -FORMAT_COMMAND=(lint --strict) -for arg in "$@"; do - if [ "$arg" == "--fix" ]; then - FORMAT_COMMAND=(format --in-place) - fi -done - -SWIFTFORMAT_BIN=${SWIFTFORMAT_BIN:-$(command -v swift-format)} || fatal "❌ SWIFTFORMAT_BIN unset and no swift-format on PATH" - -git -C "${REPO_ROOT}" ls-files -z '*.swift' \ - | grep -z -v -e 'Tests/ContainerRegistry/Resources' \ - -e 'Vendor' \ - | xargs -0 "${SWIFTFORMAT_BIN}" "${FORMAT_COMMAND[@]}" --parallel \ - && SWIFT_FORMAT_RC=$? || SWIFT_FORMAT_RC=$? - -if [ "${SWIFT_FORMAT_RC}" -ne 0 ]; then - fatal "❌ Running swift-format produced errors. - - To fix, run the following command: - - % ./scripts/run-swift-format.sh --fix - " - exit "${SWIFT_FORMAT_RC}" -fi - -log "✅ Ran swift-format with no errors." diff --git a/scripts/soundness.sh b/scripts/soundness.sh deleted file mode 100755 index e1d52fb..0000000 --- a/scripts/soundness.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env bash -##===----------------------------------------------------------------------===## -## -## This source file is part of the SwiftContainerPlugin open source project -## -## Copyright (c) 2024 Apple Inc. and the SwiftContainerPlugin project authors -## Licensed under Apache License v2.0 -## -## See LICENSE.txt for license information -## See CONTRIBUTORS.txt for the list of SwiftContainerPlugin project authors -## -## SPDX-License-Identifier: Apache-2.0 -## -##===----------------------------------------------------------------------===## -##===----------------------------------------------------------------------===## -## -## This source file is part of the SwiftOpenAPIGenerator open source project -## -## Copyright (c) 2023 Apple Inc. and the SwiftOpenAPIGenerator project authors -## Licensed under Apache License v2.0 -## -## See LICENSE.txt for license information -## See CONTRIBUTORS.txt for the list of SwiftOpenAPIGenerator project authors -## -## SPDX-License-Identifier: Apache-2.0 -## -##===----------------------------------------------------------------------===## -set -euo pipefail - -log() { printf -- "** %s\n" "$*" >&2; } -error() { printf -- "** ERROR: %s\n" "$*" >&2; } -fatal() { error "$@"; exit 1; } - -CURRENT_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -NUM_CHECKS_FAILED=0 - -FIX_FORMAT="" -for arg in "$@"; do - if [ "$arg" == "--fix" ]; then - FIX_FORMAT="--fix" - fi -done - -SCRIPT_PATHS=( - "${CURRENT_SCRIPT_DIR}/check-for-broken-symlinks.sh" - "${CURRENT_SCRIPT_DIR}/check-for-unacceptable-language.sh" - "${CURRENT_SCRIPT_DIR}/check-license-headers.sh" -) - -for SCRIPT_PATH in "${SCRIPT_PATHS[@]}"; do - log "Running ${SCRIPT_PATH}..." - if ! bash "${SCRIPT_PATH}"; then - ((NUM_CHECKS_FAILED+=1)) - fi -done - -log "Running swift-format..." -bash "${CURRENT_SCRIPT_DIR}"/run-swift-format.sh $FIX_FORMAT > /dev/null -FORMAT_EXIT_CODE=$? -if [ $FORMAT_EXIT_CODE -ne 0 ]; then - ((NUM_CHECKS_FAILED+=1)) -fi - -if [ "${NUM_CHECKS_FAILED}" -gt 0 ]; then - fatal "❌ ${NUM_CHECKS_FAILED} soundness check(s) failed." -fi - -log "✅ All soundness check(s) passed." diff --git a/scripts/unacceptable-language.txt b/scripts/unacceptable-language.txt deleted file mode 100644 index 6ac4a98..0000000 --- a/scripts/unacceptable-language.txt +++ /dev/null @@ -1,15 +0,0 @@ -blacklist -whitelist -slave -master -sane -sanity -insane -insanity -kill -killed -killing -hang -hung -hanged -hanging