diff --git a/.circleci/config.yml b/.circleci/config.yml index 236afcd837b..3a9d081d284 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,6 +17,16 @@ parameters: default: false commands: + install-linux-mbx-ci: + steps: + - run: + name: "Install mbx-ci" + command: | + mkdir -p ./bin + curl -fsSL https://mapbox-release-engineering.s3.amazonaws.com/mbx-ci/latest/mbx-ci-linux-amd64 > mbx-ci + sudo mv mbx-ci /usr/local/bin/ + chmod 755 /usr/local/bin/mbx-ci + echo "mbx-ci version: $(mbx-ci --version)" install-mbx-ci: steps: - macos/install-rosetta @@ -25,6 +35,14 @@ commands: command: | curl -Ls https://mapbox-release-engineering.s3.amazonaws.com/mbx-ci/latest/mbx-ci-darwin-amd64 > /usr/local/bin/mbx-ci chmod 755 /usr/local/bin/mbx-ci + install-linux-s5cmd: + steps: + - run: + name: "Install s5cmd" + command: | + curl -fsSL https://github.com/peak/s5cmd/releases/download/v2.3.0/s5cmd_2.3.0_Linux-64bit.tar.gz | tar xvz + sudo mv s5cmd /usr/local/bin/ + echo "s5cmd version: $(s5cmd version)" notify-build-finished: parameters: notify_success: @@ -695,46 +713,79 @@ jobs: default: "14.3.1" macos: xcode: << parameters.xcode >> + resource_class: m4pro.medium environment: HOMEBREW_NO_AUTO_UPDATE: 1 - resource_class: m4pro.medium steps: - checkout - *restore-cache-gems - - *restore-cache-podmaster - *install-gems - *prepare-netrc-file - *add-github-to-known-hosts - - install-mbx-ci - run: name: Generate docs command: | - OUTPUT=$( echo << pipeline.git.tag >> | sed 's/^v//' ) - export OUTPUT="${OUTPUT:-documentation}" - echo "export OUTPUT=$OUTPUT" >> $BASH_ENV - ./scripts/document.sh - cp -a "$OUTPUT" /tmp/generated-docs - - *save-cache-podmaster + TAG="<< pipeline.git.tag >>" + if [ -n "$TAG" ]; then + VERSION=${TAG#v} + else + # Dummy version for non-tagged builds. + VERSION=0.0.0 + fi + OUTPUT_PATH="build/docs/$VERSION" + echo "export OUTPUT_PATH=$OUTPUT_PATH" >> $BASH_ENV + ./scripts/generate-docs.sh "$VERSION" "$OUTPUT_PATH" - *save-cache-gems + - persist_to_workspace: + root: ./ + paths: + - build/docs - run: - name: Compress Docs - command: tar -cvzf /tmp/docs.tar /tmp/generated-docs + name: Compress docs + command: | + mkdir -p build/archives + tar -cvzf build/archives/navsdk-v2-docs.tar $OUTPUT_PATH - store_artifacts: - path: /tmp/docs.tar - destination: docs + path: build/archives/navsdk-v2-docs.tar + destination: navsdk-v2-docs + - notify-build-finished + + publish-docs-job: + docker: + - image: cimg/base:current + resource_class: small + environment: + HOMEBREW_NO_AUTO_UPDATE: 1 + MBX_CI_DOMAIN: o619qyc20d.execute-api.us-east-1.amazonaws.com + TARGET_ENVIRONMENT: docs.mapbox.com + steps: - when: - condition: << pipeline.git.tag >> + condition: << pipeline.git.tag >> =~ /^v2\.\d+\.\d+(-.+)?$/ steps: - - run: - name: Push docs to publisher-production - command: | - git remote set-url origin "https://x-access-token:$(mbx-ci github writer public token)@github.com/mapbox/mapbox-navigation-ios.git" - git config user.email "release-bot@mapbox.com" - git config user.name "Mapbox Releases" - VERSION="${OUTPUT}" scripts/publish-docs.sh - - notify-build-finished: - notify_success: true - - notify-build-finished + - checkout + - *add-github-to-known-hosts + - attach_workspace: + at: . + - install-linux-mbx-ci + - install-linux-s5cmd + - run: + name: Publish docs + command: | + TAG="<< pipeline.git.tag >>" + if [ -z "$TAG" ]; then + echo "ERROR: Missing git tag. A tag is required to publish documentation." + exit 1 + fi + VERSION=${TAG#v} + + if ! mbx-ci aws setup; then + echo "ERROR: Could not setup AWS credentials." + exit 1 + fi + + SOURCE_PATH="build/docs/$VERSION" + ./scripts/publish-docs.sh "$VERSION" "$TARGET_ENVIRONMENT" "$SOURCE_PATH" + - notify-build-finished update-version-job: parameters: @@ -946,11 +997,21 @@ workflows: clean_build: false context: Slack Orb - generate-docs-job: - name: Generate / Publish Documentation + name: Generate Documentation context: Slack Orb filters: tags: - only: /^v\d+\.\d+\.\d+(-.+)?$/ + only: /^v2\.\d+\.\d+(-.+)?$/ + - publish-docs-job: + name: Publish Documentation + context: Slack Orb + requires: + - Generate Documentation + filters: + branches: + ignore: /.*/ + tags: + only: /^v2\.\d+\.\d+(-.+)?$/ - ios-trigger-metrics: filters: branches: diff --git a/docs/README.md b/docs/README.md index a23bfde9b01..86e27a600c4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,3 +1,3 @@ ## Generating documentation locally -Make sure you’ve got Bundler installed, then run `scripts/document.sh`. +Make sure you’ve got Bundler installed, then run `scripts/generate-docs.sh`. diff --git a/scripts/document.sh b/scripts/generate-docs.sh similarity index 66% rename from scripts/document.sh rename to scripts/generate-docs.sh index dea66aadfc2..457a8dd80ad 100755 --- a/scripts/document.sh +++ b/scripts/generate-docs.sh @@ -1,8 +1,42 @@ #!/usr/bin/env bash -set -e -set -o pipefail -set -u +set -euo pipefail + +if [ $# -ne 2 ]; then + echo "Usage: $0 " + echo "Example: $0 2.20.3 build/docs/2.20.3" + exit 1 +fi + +SHORT_VERSION=$1 +OUTPUT=$2 + +if [[ ! "${SHORT_VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-.+)?$ ]]; then + echo "Error: Version '${SHORT_VERSION}' does not match the required format." + echo "Format: X.Y.Z or X.Y.Z-suffix (e.g., 2.20.3, 2.21.0-beta.1)" + exit 1 +fi + +# Safety checks for output directory +ABS_PWD=$(pwd -P) +if [[ "$OUTPUT" == /* ]]; then + # Absolute path + if [[ "$OUTPUT" != "$ABS_PWD"* ]]; then + echo "Error: Output directory '$OUTPUT' must be within the current working directory '$ABS_PWD'." + exit 1 + fi +else + # Relative path + if [[ "$OUTPUT" == *".."* ]]; then + echo "Error: Output directory '$OUTPUT' cannot contain parent directory traversal ('..')." + exit 1 + fi +fi + +if [[ "${OUTPUT}" == "/" ]] || [[ "${OUTPUT}" == "${HOME}" ]]; then + echo "Error: Output directory cannot be root or home directory." + exit 1 +fi bundle check || bundle install @@ -13,12 +47,9 @@ if [[ -z $(which "${SOURCEKITTEN_PATH}") ]]; then exit 1 fi -BRANCH=$( git describe --tags --match=v*.*.* --abbrev=0 ) -SHORT_VERSION=$( echo ${BRANCH} | sed 's/^v//' ) RELEASE_VERSION=$( echo ${SHORT_VERSION} | sed -e 's/-.*//' ) MINOR_VERSION=$( echo ${SHORT_VERSION} | grep -Eo '^\d+\.\d+' ) - -OUTPUT=${OUTPUT:-${SHORT_VERSION:-documentation}} +LONG_VERSION="v${SHORT_VERSION}" DEFAULT_THEME="docs/theme" THEME=${JAZZY_THEME:-$DEFAULT_THEME} @@ -48,7 +79,7 @@ DESTINATION="generic/platform=iOS" bundle exec jazzy \ --config docs/jazzy.yml \ --sdk iphonesimulator \ - --github-file-prefix "https://github.com/mapbox/mapbox-navigation-ios/tree/${BRANCH}" \ + --github-file-prefix "https://github.com/mapbox/mapbox-navigation-ios/tree/${LONG_VERSION}" \ --readme ${README} \ --documentation="docs/guides/*.md" \ --root-url "${BASE_URL}/navigation/api/${RELEASE_VERSION}/" \ @@ -59,7 +90,10 @@ bundle exec jazzy \ 2>&1 | tee docs.output rm core.json ui.json - + +# Filter out known harmless warnings (needed for Xcode 15+) +sed -i '' '/`AppKit` has no USR/d' docs.output + if egrep -e "(WARNING)|(USR)" docs.output; then echo "Please eliminate Jazzy warnings" exit 1 diff --git a/scripts/publish-docs.sh b/scripts/publish-docs.sh index 8d6e5190b30..43155f7c049 100755 --- a/scripts/publish-docs.sh +++ b/scripts/publish-docs.sh @@ -1,21 +1,51 @@ #!/usr/bin/env bash -set -e -set -o pipefail -set -u +set -euo pipefail -if ! [[ -d "${VERSION}" ]]; then - echo "${VERSION} directory does not exist" - exit 1 +if [ $# -ne 3 ]; then + echo "Usage: $0 " + echo "Example: $0 2.20.3 docs.mapbox.com-staging build/docs/2.20.3" + exit 1 fi -if ! [[ "${VERSION}" =~ ^([0-9]+\.){2}[0-9]+(-.+)?$ ]]; then - echo "Set \$VERSION to a valid semver version" - exit 1 +VERSION=$1 +TARGET_ENVIRONMENT=$2 +SOURCE_PATH=$3 + +# Validate version format +if [[ ! "${VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-.+)?$ ]]; then + echo "Error: Version '${VERSION}' does not match the required format." + echo "Format: X.Y.Z or X.Y.Z-suffix (e.g., 2.20.3, 2.21.0-beta.1)" + exit 1 +fi + +# Validate target environment +if [[ "${TARGET_ENVIRONMENT}" != "docs.mapbox.com" ]] && [[ "${TARGET_ENVIRONMENT}" != "docs.mapbox.com-staging" ]]; then + echo "Error: Target environment '${TARGET_ENVIRONMENT}' is invalid." + echo "Allowed values: docs.mapbox.com, docs.mapbox.com-staging" + exit 1 +fi + +# Validate source path +if [[ ! -f "${SOURCE_PATH}/index.html" ]]; then + echo "Error: Documentation not found at '${SOURCE_PATH}'." + echo "Missing index.html file." + exit 1 fi -git checkout -- . -git checkout publisher-production -git add "${VERSION}" -git commit -m "v${VERSION} [skip ci]" -git push origin publisher-production +echo "########################################################" +echo "PUBLISHING DOCS FOR VERSION: ${VERSION}" +echo "########################################################" +echo "SOURCE_PATH: ${SOURCE_PATH}" +echo "TARGET_ENVIRONMENT: ${TARGET_ENVIRONMENT}" +echo "########################################################" + +s5cmd sync \ + "${SOURCE_PATH}/*" \ + "s3://${TARGET_ENVIRONMENT}/ios/navigation/api/${VERSION}/" + +echo "########################################################" +echo "DOCS PUBLISHED SUCCESSFULLY" +echo "URL: https://${TARGET_ENVIRONMENT}/ios/navigation/api/${VERSION}/" +echo "########################################################" +