diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..41f25760 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,17 @@ +name: release +on: + release: + types: [published] +env: + CI_XCODE: '/Applications/Xcode_15.4.app/Contents/Developer' + +jobs: + docs: + runs-on: macos-14 + steps: + - uses: actions/checkout@v4 + - name: Build and Deploy Docs + run: set -o pipefail && env NSUnbufferedIO=YES Scripts/update-gh-pages-documentation-site + env: + CURRENT_BRANCH_NAME: release + DEVELOPER_DIR: ${{ env.CI_XCODE }} diff --git a/README.md b/README.md index 2a7afa5e..b2aaab71 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # CareKitEssentials +[![Documentation](https://img.shields.io/badge/read_-docs-2196f3.svg)](https://swiftpackageindex.com/netreconlab/CareKitEssentials/documentation/) +[![Tuturiol](https://img.shields.io/badge/read_-tuturials-2196f3.svg)](https://netreconlab.github.io/CareKitEssentials/release/tutorials/carekitessentials/) [![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fnetreconlab%2FCareKitEssentials%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/netreconlab/CareKitEssentials) [![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fnetreconlab%2FCareKitEssentials%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/netreconlab/CareKitEssentials) ![Xcode 13.2+](https://img.shields.io/badge/xcode-13.2%2B-blue.svg) @@ -7,7 +9,7 @@ ![Codecov](https://codecov.io/gh/netreconlab/CareKitEssentials/branches/main/graph/badge.svg) [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/netreconlab/ParseCareKit/#license) -Provides essential cards, views, models, protocols, and extentions to expedite building [CareKit](https://github.com/carekit-apple/CareKit) based applications. +Provides essential cards, views, models, protocols, and extensions to expedite building [CareKit](https://github.com/carekit-apple/CareKit) based applications. ## Entensions A number of public extensions are available to make using CareKit easier. All of the extensions can be found in the [Extensions](https://github.com/netreconlab/CareKitEssentials/tree/main/Sources/CareKitEssentials/Extensions) folder. diff --git a/Scripts/generate-documentation b/Scripts/generate-documentation new file mode 100644 index 00000000..7182217b --- /dev/null +++ b/Scripts/generate-documentation @@ -0,0 +1,140 @@ +#!/bin/bash +# +# Copyright (c) 2022, Apple Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation and/or +# other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder(s) nor the names of any contributors +# may be used to endorse or promote products derived from this software without +# specific prior written permission. No license is granted to the trademarks of +# the copyright holders even if such marks are included in this software. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# A `realpath` alternative using the default C implementation. +filepath() { + [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}" +} + +# First get the absolute path to this file so we can get the absolute file path to the Swift-DocC root source dir. +PROJECT_ROOT="$(dirname $(dirname $(filepath $0)))" +DOCS_DIR="$PROJECT_ROOT/.build/swift-docc" +SGFS_DIR="$DOCS_DIR/symbol-graph-files" +TEMP_WORKSPACE_DIR="$DOCS_DIR/temporary-workspace-holding-directory" + +DOCC_CMD=convert +OUTPUT_PATH="$DOCS_DIR/CareKitEssentials.doccarchive" +HOSTING_BASE_PATH="" +PUBLISH="NO" + +# Process command line arguments +OUTPUT_PATH_PROCESSED=0 +HOSTING_BASE_PATH_PROCESSED=0 +while test $# -gt 0; do + case "$1" in + --help) + echo "Usage: $(basename $0) [] [] [--preview] [--publish] [--help]" + echo + echo "Builds CareKitEssentials and generates or previews the Swift-DocC documentation." + echo + echo " --preview: Starts a preview server after generating documentation." + echo " --publish: Configures the documentation build for publishing on GitHub pages." + echo + exit 0 + ;; + --preview) + DOCC_CMD=preview + shift + ;; + --publish) + PUBLISH="YES" + shift + ;; + *) + if [ ${OUTPUT_PATH_PROCESSED} -eq 0 ]; then + OUTPUT_PATH="$1" + OUTPUT_PATH_PROCESSED=1 + elif [ ${HOSTING_BASE_PATH_PROCESSED} -eq 0 ]; then + HOSTING_BASE_PATH="$1" + HOSTING_BASE_PATH_PROCESSED=1 + else + echo "Unrecognised argument \"$1\"" + exit 1 + fi + ;; + esac + shift +done + +if [ "$PUBLISH" = "YES" ]; then + if [ ${HOSTING_BASE_PATH_PROCESSED} -eq 0 ]; then + echo "A hosting base path must be provided if the '--publish' flag is passed." + echo "See '--help' for details." + exit 1 + fi +fi + +# Create the output directory for the symbol graphs if needed. +mkdir -p "$DOCS_DIR" +mkdir -p "$SGFS_DIR" +rm -f $SGFS_DIR/*.* + +cd "$PROJECT_ROOT" + +# Temporarily move the Xcode workspace aside so that xcodebuild uses the Swift package directly +mkdir "$TEMP_WORKSPACE_DIR" +mv CareKitEssentials.xcodeproj "$TEMP_WORKSPACE_DIR/CareKitEssentials.xcodeproj" + +xcodebuild clean build -scheme CareKitEssentials \ + -destination generic/platform=iOS \ + OTHER_SWIFT_FLAGS="-emit-symbol-graph -emit-symbol-graph-dir '$SGFS_DIR'" | xcpretty + +mv "$TEMP_WORKSPACE_DIR/CareKitEssentials.xcodeproj" ./CareKitEssentials.xcodeproj +rm -r "$TEMP_WORKSPACE_DIR" + +# Pretty print DocC JSON output so that it can be consistently diffed between commits +export DOCC_JSON_PRETTYPRINT="YES" + +# By default pass the --index flag so we produce a full DocC archive. +EXTRA_DOCC_FLAGS="--index" + +# If building for publishing, don't pass the --index flag but pass additional flags for +# static hosting configuration. +if [ "$PUBLISH" = "YES" ]; then + EXTRA_DOCC_FLAGS="--transform-for-static-hosting --hosting-base-path CareKitEssentials/$HOSTING_BASE_PATH" +fi + +# Handle the case where a DocC catalog does not exist in the CareKitEssentials repo +if [ -d Sources/CareKitEssentials/Documentation.docc ]; then + # The DocC catalog exists, so pass it to the docc invocation. + DOCC_CMD="$DOCC_CMD Sources/CareKitEssentials/Documentation.docc" +fi + +xcrun docc $DOCC_CMD \ + --additional-symbol-graph-dir "$SGFS_DIR" \ + --output-path "$OUTPUT_PATH" $EXTRA_DOCC_FLAGS \ + --fallback-display-name CareKitEssentials \ + --fallback-bundle-identifier edu.usc.netreconlab.CareKitEssentials \ + --fallback-bundle-version 1.0.0 + +if [[ "$DOCC_CMD" == "convert"* ]]; then + echo + echo "Generated DocC archive at: $OUTPUT_PATH" +fi diff --git a/Scripts/update-gh-pages-documentation-site b/Scripts/update-gh-pages-documentation-site new file mode 100644 index 00000000..3dc17a77 --- /dev/null +++ b/Scripts/update-gh-pages-documentation-site @@ -0,0 +1,80 @@ +#!/bin/bash +# +# Copyright (c) 2022, Apple Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation and/or +# other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder(s) nor the names of any contributors +# may be used to endorse or promote products derived from this software without +# specific prior written permission. No license is granted to the trademarks of +# the copyright holders even if such marks are included in this software. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set -eu + +# A `realpath` alternative using the default C implementation. +filepath() { + [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}" +} + +PROJECT_ROOT="$(dirname $(dirname $(filepath $0)))" + +# Set current directory to the repository root +cd "$PROJECT_ROOT" + +# Use git worktree to checkout the gh-pages branch of this repository in a gh-pages sub-directory +git fetch +git worktree add --checkout gh-pages origin/gh-pages + +# Get the name of the current branch to use as the subdirectory for the deployment +if [ -z ${CURRENT_BRANCH_NAME+x} ]; then + CURRENT_BRANCH_NAME=`git rev-parse --abbrev-ref HEAD` +fi + +# Replace any forward slashes in the current branch name with dashes +DEPLOYMENT_SUBDIRECTORY=${CURRENT_BRANCH_NAME//\//-} + +# Create a subdirectory for the current branch name if it doesn't exist +mkdir -p "./gh-pages/$DEPLOYMENT_SUBDIRECTORY" + +# Generate documentation output it +# to the /docs subdirectory in the gh-pages worktree directory. +./Scripts/generate-documentation "$PROJECT_ROOT/gh-pages/$DEPLOYMENT_SUBDIRECTORY" "$DEPLOYMENT_SUBDIRECTORY" --publish + +# Save the current commit we've just built documentation from in a variable +CURRENT_COMMIT_HASH=`git rev-parse --short HEAD` + +# Commit and push our changes to the gh-pages branch +cd gh-pages +git add "$DEPLOYMENT_SUBDIRECTORY" + +if [ -n "$(git status --porcelain)" ]; then + echo "Documentation changes found. Commiting the changes to the 'gh-pages' branch and pushing to origin." + git commit -m "Update documentation to $CURRENT_COMMIT_HASH on '$CURRENT_BRANCH_NAME'" + git push origin HEAD:gh-pages +else + # No changes found, nothing to commit. + echo "No documentation changes found." +fi + +# Delete the git worktree we created +cd .. +git worktree remove gh-pages