|
1 | 1 | name: Publish Documentation |
2 | 2 | on: |
3 | 3 | push: |
4 | | - branches: |
5 | | - - main |
| 4 | + branches: [main] |
| 5 | + workflow_dispatch: |
| 6 | + inputs: |
| 7 | + deploy_as_release: |
| 8 | + description: 'Deploy as release version (e.g., v1.2.3) - will deploy the docs as if this is a release with this version' |
| 9 | + required: false |
| 10 | + type: string |
| 11 | + default: '' |
| 12 | + force_deploy: |
| 13 | + description: 'Force deployment even on non-main branches (for testing)' |
| 14 | + required: false |
| 15 | + type: boolean |
| 16 | + default: false |
| 17 | + skip_build: |
| 18 | + description: 'Skip build-and-test job (use existing artifacts)' |
| 19 | + required: false |
| 20 | + type: boolean |
| 21 | + default: false |
| 22 | + workflow_call: |
| 23 | + inputs: |
| 24 | + deploy_as_release: |
| 25 | + description: 'Deploy as release version (e.g., v1.2.3) - will deploy the docs as if this is a release with this version' |
| 26 | + required: false |
| 27 | + type: string |
| 28 | + default: '' |
| 29 | + skip_build: |
| 30 | + description: 'Skip build-and-test job (assumes artifacts already exist)' |
| 31 | + required: false |
| 32 | + type: boolean |
| 33 | + default: false |
| 34 | + secrets: |
| 35 | + SIEMENS_NPM_TOKEN: |
| 36 | + required: false |
| 37 | + SIEMENS_NPM_USER: |
| 38 | + required: false |
| 39 | + MAPTILER_KEY: |
| 40 | + required: false |
| 41 | + |
| 42 | +env: |
| 43 | + PYTHON_VERSION: '3.11' |
| 44 | + NODE_VERSION: '20' |
| 45 | + VERSIONED_BUCKET_NAME: simpl-element-release |
| 46 | + CLOUDFRONT_DOMAIN: d2uqfzn4lxgtwv.cloudfront.net |
6 | 47 |
|
7 | 48 | jobs: |
8 | 49 | build-and-test: |
| 50 | + if: ${{ !inputs.skip_build && github.event.inputs.skip_build != 'true' }} |
9 | 51 | uses: ./.github/workflows/build-and-test.yaml |
10 | 52 | secrets: |
11 | 53 | SIEMENS_NPM_TOKEN: ${{ secrets.SIEMENS_NPM_TOKEN }} |
12 | 54 | SIEMENS_NPM_USER: ${{ secrets.SIEMENS_NPM_USER }} |
13 | 55 | MAPTILER_KEY: ${{ secrets.MAPTILER_KEY }} |
14 | 56 |
|
15 | | - publish-documentation: |
| 57 | + # Simple deployment for main branch (no versioning) |
| 58 | + publish-documentation-main: |
16 | 59 | runs-on: ubuntu-24.04 |
| 60 | + needs: |
| 61 | + - build-and-test |
| 62 | + if: >- |
| 63 | + ${{ |
| 64 | + needs.build-and-test.result == 'success' && |
| 65 | + github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && |
| 66 | + !inputs.deploy_as_release |
| 67 | + }} |
17 | 68 | permissions: |
| 69 | + contents: write |
18 | 70 | pages: write |
19 | 71 | id-token: write |
20 | | - needs: |
21 | | - - build-and-test |
22 | 72 | steps: |
23 | | - - uses: actions/configure-pages@v5 |
24 | | - - uses: actions/download-artifact@v7 |
| 73 | + - name: Download documentation artifact |
| 74 | + uses: actions/download-artifact@v7 |
25 | 75 | with: |
26 | 76 | name: pages |
27 | 77 | path: dist/design |
28 | | - - uses: actions/upload-pages-artifact@v4 |
| 78 | + |
| 79 | + - name: Setup Pages |
| 80 | + uses: actions/configure-pages@v5 |
| 81 | + |
| 82 | + - name: Upload Pages artifact |
| 83 | + uses: actions/upload-pages-artifact@v4 |
29 | 84 | with: |
30 | 85 | path: 'dist/design' |
31 | | - - uses: actions/deploy-pages@v4 |
| 86 | + |
| 87 | + - name: Deploy to GitHub Pages |
| 88 | + uses: actions/deploy-pages@v4 |
| 89 | + |
| 90 | + # Versioned deployment for releases (S3 only, not GitHub Pages) |
| 91 | + publish-documentation-release: |
| 92 | + runs-on: ubuntu-24.04 |
| 93 | + needs: |
| 94 | + - build-and-test |
| 95 | + if: ${{ always() && (needs.build-and-test.result == 'success' || inputs.skip_build) && inputs.deploy_as_release }} |
| 96 | + permissions: |
| 97 | + contents: write |
| 98 | + id-token: write |
| 99 | + steps: |
| 100 | + - name: Checkout |
| 101 | + uses: actions/checkout@v4 |
| 102 | + with: |
| 103 | + fetch-depth: 0 |
| 104 | + |
| 105 | + - name: Determine deployment targets |
| 106 | + id: deploy |
| 107 | + run: | |
| 108 | + # Initialize all outputs |
| 109 | + DEPLOY_MAJOR="false" |
| 110 | + MAJOR_VERSION="" |
| 111 | + VERSION="" |
| 112 | + SHOULD_DEPLOY="false" |
| 113 | +
|
| 114 | + DEPLOY_AS_RELEASE="${{ github.event.inputs.deploy_as_release || inputs.deploy_as_release }}" |
| 115 | +
|
| 116 | + # Validate and extract version info |
| 117 | + if [[ -n "$DEPLOY_AS_RELEASE" ]]; then |
| 118 | + # Ensure version starts with 'v' |
| 119 | + if [[ ! "$DEPLOY_AS_RELEASE" =~ ^v[0-9]+\.[0-9]+\.[0-9]+.*$ ]]; then |
| 120 | + echo "Error: Deploy as release version must be in format 'v1.2.3' or 'v1.2.3-suffix'" |
| 121 | + echo "Provided: '$DEPLOY_AS_RELEASE'" |
| 122 | + exit 1 |
| 123 | + fi |
| 124 | +
|
| 125 | + VERSION="${DEPLOY_AS_RELEASE#v}" |
| 126 | + MAJOR_VERSION="v$(echo "$VERSION" | cut -d. -f1)" |
| 127 | +
|
| 128 | + # Check if it's a pre-release (contains -, like v1.0.0-rc1) |
| 129 | + IS_PRERELEASE="false" |
| 130 | + if [[ "$VERSION" =~ -.*$ ]]; then |
| 131 | + IS_PRERELEASE="true" |
| 132 | + fi |
| 133 | +
|
| 134 | + # Deploy to major version except for pre/next/rc releases |
| 135 | + if [[ "$IS_PRERELEASE" == "false" ]]; then |
| 136 | + DEPLOY_MAJOR="true" |
| 137 | + SHOULD_DEPLOY="true" |
| 138 | + fi |
| 139 | + fi |
| 140 | +
|
| 141 | + echo "deploy_major=$DEPLOY_MAJOR" >> $GITHUB_OUTPUT |
| 142 | + echo "major_version=$MAJOR_VERSION" >> $GITHUB_OUTPUT |
| 143 | + echo "version=$VERSION" >> $GITHUB_OUTPUT |
| 144 | + echo "should_deploy=$SHOULD_DEPLOY" >> $GITHUB_OUTPUT |
| 145 | +
|
| 146 | + echo "DEPLOYMENT PLAN" |
| 147 | + echo "===============" |
| 148 | + echo "Branch: ${{ github.ref }}" |
| 149 | + echo "Trigger: ${{ github.event_name }}" |
| 150 | + echo "Major ($MAJOR_VERSION): $DEPLOY_MAJOR" |
| 151 | +
|
| 152 | + # Exit early if we should not deploy |
| 153 | + if [[ "$SHOULD_DEPLOY" != "true" ]]; then |
| 154 | + echo "Skipping deployment (pre-release version)" |
| 155 | + exit 1 |
| 156 | + fi |
| 157 | +
|
| 158 | + - name: Download documentation artifact |
| 159 | + uses: actions/download-artifact@v7 |
| 160 | + with: |
| 161 | + name: pages |
| 162 | + path: new-docs |
| 163 | + |
| 164 | + - name: Configure AWS credentials |
| 165 | + uses: aws-actions/configure-aws-credentials@v5.1.1 |
| 166 | + with: |
| 167 | + role-to-assume: arn:aws:iam::974483672234:role/simpl-element-release |
| 168 | + role-session-name: element-release-docs |
| 169 | + aws-region: eu-west-1 |
| 170 | + |
| 171 | + - name: List existing versions from S3 |
| 172 | + run: | |
| 173 | + mkdir -p deploy-site |
| 174 | +
|
| 175 | + # List existing version directories from S3 (no download needed) |
| 176 | + echo "Listing existing versions from S3..." |
| 177 | + aws s3 ls s3://${{ env.VERSIONED_BUCKET_NAME }}/ || echo "No existing versions found" |
| 178 | +
|
| 179 | + - name: Update with new version(s) |
| 180 | + run: | |
| 181 | + # Deploy to major version directory |
| 182 | + MAJOR_VERSION="${{ steps.deploy.outputs.major_version }}" |
| 183 | +
|
| 184 | + echo "Updating /$MAJOR_VERSION/..." |
| 185 | + # Remove old version to ensure clean deployment |
| 186 | + rm -rf "deploy-site/$MAJOR_VERSION" |
| 187 | + mkdir -p "deploy-site/$MAJOR_VERSION" |
| 188 | + cp -r new-docs/* "deploy-site/$MAJOR_VERSION/" |
| 189 | +
|
| 190 | + # Add base tag to docs HTML files only (exclude element-examples, dashboards-demo, coverage) |
| 191 | + find "deploy-site/$MAJOR_VERSION" -name "*.html" -type f \ |
| 192 | + ! -path "*/element-examples/*" \ |
| 193 | + ! -path "*/dashboards-demo/*" \ |
| 194 | + ! -path "*/coverage/*" \ |
| 195 | + -exec sed -i.bak "s|<head>|<head>\n <base href=\"/$MAJOR_VERSION/\">|" {} \; |
| 196 | +
|
| 197 | + find "deploy-site/$MAJOR_VERSION" -name "*.bak" -type f -delete |
| 198 | +
|
| 199 | + - name: Generate versions.json |
| 200 | + run: | |
| 201 | + # Generate versions.json from S3 directory listing (no download needed) |
| 202 | + echo "Generating versions.json from S3 directory listing..." |
| 203 | +
|
| 204 | + # Collect all versions from S3 |
| 205 | + ALL_VERSIONS=() |
| 206 | +
|
| 207 | + # List all existing version-specific folders from S3 (v1, v2, v48, etc.) |
| 208 | + # aws s3 ls lists directories with trailing slashes, e.g., "PRE v1/" |
| 209 | + aws s3 ls s3://${{ env.VERSIONED_BUCKET_NAME }}/ | grep "PRE v" | awk '{print $2}' | sed 's/\/$//' > s3-versions.txt || true |
| 210 | +
|
| 211 | + # Add the currently deploying version to ensure it's included |
| 212 | + MAJOR_VERSION="${{ steps.deploy.outputs.major_version }}" |
| 213 | + echo "$MAJOR_VERSION" >> s3-versions.txt |
| 214 | +
|
| 215 | + # Read all versions and remove duplicates |
| 216 | + while IFS= read -r version_name; do |
| 217 | + if [[ -n "$version_name" ]]; then |
| 218 | + ALL_VERSIONS+=("$version_name") |
| 219 | + fi |
| 220 | + done < s3-versions.txt |
| 221 | +
|
| 222 | + # Remove duplicates and sort versions in descending order |
| 223 | + SORTED_VERSIONS=($(printf '%s\n' "${ALL_VERSIONS[@]}" | sort -u -t 'v' -k 2 -n -r)) |
| 224 | +
|
| 225 | + # Find the highest version for "Latest" |
| 226 | + LATEST_VERSION="${SORTED_VERSIONS[0]}" |
| 227 | + echo "Latest version: $LATEST_VERSION" |
| 228 | +
|
| 229 | + # Build versions.json with correct order: |
| 230 | + # 1. Latest (empty version string) |
| 231 | + # 2. All versions in descending order (v48, v18, v17, etc.) |
| 232 | + # 3. Preview (redirect to element.siemens.io) |
| 233 | +
|
| 234 | + VERSIONS='[]' |
| 235 | +
|
| 236 | + # Add Latest first (empty version string points to root) |
| 237 | + latest_num=$(echo "$LATEST_VERSION" | sed 's/^v//') |
| 238 | + echo "Adding: Latest (${latest_num}.x)" |
| 239 | + VERSIONS=$(echo "$VERSIONS" | jq '. += [{"version": "", "title": "Latest"}]') |
| 240 | +
|
| 241 | + # Add all versions in descending order |
| 242 | + for version_name in "${SORTED_VERSIONS[@]}"; do |
| 243 | + version_num=$(echo "$version_name" | sed 's/^v//') |
| 244 | + echo "Adding: $version_name (${version_num}.x)" |
| 245 | + VERSIONS=$(echo "$VERSIONS" | jq --arg version "$version_name" --arg title "${version_num}.x" '. += [{"version": $version, "title": $title}]') |
| 246 | + done |
| 247 | +
|
| 248 | + # Add Preview last |
| 249 | + echo "Adding: Preview (redirect to https://element.siemens.io)" |
| 250 | + VERSIONS=$(echo "$VERSIONS" | jq '. += [{"version": "https://element.siemens.io", "title": "Preview"}]') |
| 251 | +
|
| 252 | + # Write to deploy-site/versions.json |
| 253 | + mkdir -p deploy-site |
| 254 | + echo "$VERSIONS" | jq '.' > deploy-site/versions.json |
| 255 | +
|
| 256 | + echo "Generated versions.json:" |
| 257 | + cat deploy-site/versions.json |
| 258 | +
|
| 259 | + - name: Update canonical URLs |
| 260 | + run: | |
| 261 | + SITE_URL="https://element.siemens.io/" |
| 262 | +
|
| 263 | + # Update canonical URLs for version directories |
| 264 | + MAJOR_VERSION="${{ steps.deploy.outputs.major_version }}" |
| 265 | + VERSION_URL="${SITE_URL}${MAJOR_VERSION}/" |
| 266 | +
|
| 267 | + find "deploy-site/$MAJOR_VERSION" -name "*.html" -type f -exec sed -i.bak \ |
| 268 | + -e "s|<link rel=\"canonical\" href=\"https://element.siemens.io/|<link rel=\"canonical\" href=\"${VERSION_URL}|g" \ |
| 269 | + {} \; |
| 270 | +
|
| 271 | + # Clean up backup files |
| 272 | + find deploy-site -name "*.bak" -type f -delete 2>/dev/null || true |
| 273 | +
|
| 274 | + - name: Upload to S3 |
| 275 | + run: | |
| 276 | + echo "Uploading versioned documentation to S3..." |
| 277 | +
|
| 278 | + MAJOR_VERSION="${{ steps.deploy.outputs.major_version }}" |
| 279 | +
|
| 280 | + # Upload versioned directory |
| 281 | + echo "Uploading /$MAJOR_VERSION/..." |
| 282 | + if [[ ! -d "deploy-site/$MAJOR_VERSION" ]]; then |
| 283 | + echo "Error: deploy-site/$MAJOR_VERSION directory does not exist" |
| 284 | + exit 1 |
| 285 | + fi |
| 286 | + aws s3 sync --quiet --no-progress --delete "deploy-site/$MAJOR_VERSION/" "s3://${{ env.VERSIONED_BUCKET_NAME }}/$MAJOR_VERSION/" |
| 287 | +
|
| 288 | + # If on main branch, also copy to root (without version prefix in path) |
| 289 | + if [[ "${{ github.ref }}" == "refs/heads/${{ github.event.repository.default_branch }}" ]]; then |
| 290 | + echo "On main branch - copying /$MAJOR_VERSION/ to root..." |
| 291 | + # Delete old files but exclude version directories and versions.json from sync and deletion |
| 292 | + aws s3 sync --quiet --no-progress --delete "deploy-site/$MAJOR_VERSION/" "s3://${{ env.VERSIONED_BUCKET_NAME }}/" \ |
| 293 | + --exclude "v*" \ |
| 294 | + --exclude "versions.json" |
| 295 | + fi |
| 296 | +
|
| 297 | + # Upload versions.json with short cache-control for quick updates |
| 298 | + if [[ ! -f "deploy-site/versions.json" ]]; then |
| 299 | + echo "Error: deploy-site/versions.json file does not exist" |
| 300 | + exit 1 |
| 301 | + fi |
| 302 | + aws s3 cp deploy-site/versions.json s3://${{ env.VERSIONED_BUCKET_NAME }}/versions.json \ |
| 303 | + --cache-control "max-age=60,public" |
| 304 | +
|
| 305 | + echo "Uploaded versioned documentation to S3 at s3://${{ env.VERSIONED_BUCKET_NAME }}/" |
0 commit comments