name: Build & Deploy to SharePoint Online on: workflow_dispatch: jobs: deploy: runs-on: ubuntu-latest defaults: run: working-directory: frontend steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Node.js 22 uses: actions/setup-node@v3 with: node-version: '22' cache: 'npm' cache-dependency-path: frontend/package-lock.json - name: Install dependencies run: | npm config set fetch-retries 5 npm config set fetch-retry-mintimeout 10000 npm config set fetch-retry-maxtimeout 120000 for i in 1 2 3; do npm install --legacy-peer-deps && break echo "Attempt $i failed, retrying in 20s..." sleep 20 done - name: Build & package SPFx solution run: npm run build - name: Upload .sppkg artifact uses: actions/upload-artifact@v3 with: name: approval-route-admin-sppkg path: frontend/sharepoint/solution/approval-route-admin.sppkg retention-days: 7 - name: Install CLI for Microsoft 365 run: | for i in 1 2 3; do npm install -g @pnp/cli-microsoft365@9 && break echo "Attempt $i failed, retrying in 20s..." sleep 20 done - name: Login to Microsoft 365 (certificate) run: | m365 login \ --authType certificate \ --appId "${{ vars.ENTRA_CLIENT_ID }}" \ --certificateBase64Encoded "${{ secrets.SPO_CERT_BASE64 }}" \ --thumbprint "${{ secrets.SPO_CERT_THUMBPRINT }}" \ --tenant "${{ vars.ENTRA_TENANT_ID }}" - name: Upload & Deploy to App Catalog env: SOLUTION_ID: "ce823ddf-e35c-460f-a92d-ddb4ef5fc494" CATALOG_SITE: "https://tnsukz.sharepoint.com/sites/appcatalog" SPPKG: "sharepoint/solution/approval-route-admin.sppkg" FILE_NAME: "approval-route-admin.sppkg" run: | # Получаем токен через уже аутентифицированный m365 CLI TOKEN=$(m365 util accesstoken get --resource https://tnsukz.sharepoint.com --output text) echo "Token length: ${#TOKEN}" echo ">>> Uploading to App Catalog" HTTP=$(curl -s -o /tmp/upload.json -w "%{http_code}" -X POST \ "${CATALOG_SITE}/_api/web/GetFolderByServerRelativeUrl('/sites/appcatalog/AppCatalog')/Files/add(overwrite=true,url='${FILE_NAME}')" \ -H "Authorization: Bearer ${TOKEN}" \ -H "X-RequestDigest: 0x0" \ -H "Accept: application/json;odata=nometadata" \ -H "Content-Type: application/octet-stream" \ --data-binary @"${SPPKG}" || echo "000") echo "Upload HTTP: ${HTTP}" cat /tmp/upload.json [ "$HTTP" = "200" ] || [ "$HTTP" = "201" ] || exit 1 echo ">>> Deploying app (id: ${SOLUTION_ID})" HTTP=$(curl -s -o /tmp/deploy.json -w "%{http_code}" -X POST \ "${CATALOG_SITE}/_api/web/tenantappcatalog/AvailableApps/GetById('${SOLUTION_ID}')/deploy" \ -H "Authorization: Bearer ${TOKEN}" \ -H "X-RequestDigest: 0x0" \ -H "Accept: application/json;odata=nometadata" \ -H "Content-Type: application/json" \ -d '{"skipFeatureDeployment":true}' || echo "000") echo "Deploy HTTP: ${HTTP}" cat /tmp/deploy.json [ "$HTTP" = "200" ] || [ "$HTTP" = "204" ] || exit 1 echo ">>> Done"