-
Notifications
You must be signed in to change notification settings - Fork 33
Update build-and-deploy.yml #189
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| determine-environment: | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| environment: ${{ steps.set-env.outputs.environment }} | ||
| steps: | ||
| - name: Determine environment | ||
| id: set-env | ||
| run: | | ||
| if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then | ||
| echo "environment=${{ github.event.inputs.environment }}" >> $GITHUB_OUTPUT | ||
| elif [[ "${{ github.ref }}" == "refs/heads/main" ]]; then | ||
| echo "environment=production" >> $GITHUB_OUTPUT | ||
| else | ||
| echo "environment=development" >> $GITHUB_OUTPUT | ||
| fi | ||
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 3 months ago
To fix the problem, add an explicit permissions block to the determine-environment job, granting it the minimal possible permissions to execute its function. Since this job does not interact with repository contents, issues, or pull requests—and merely determines the environment by reading workflow inputs—it should only require read access to repository contents, or even less if possible. The most minimal and future-proof approach is to set all permissions to none, unless "contents: read" is strictly necessary (for example, if the job or future steps might require reading code). We can add:
permissions:
contents: reador, to further restrict:
permissions:
contents: noneFor now, "contents: read" is a safe minimal choice that will satisfy CodeQL, in line with other jobs’ minimal permissions.
Edit the .github/workflows/build-and-deploy.yml file by adding the permissions block right under runs-on: ubuntu-latest for the determine-environment job (line 21).
-
Copy modified lines R22-R23
| @@ -19,6 +19,8 @@ | ||
| jobs: | ||
| determine-environment: | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| outputs: | ||
| environment: ${{ steps.set-env.outputs.environment }} | ||
| steps: |
| deploy: | ||
| runs-on: ubuntu-latest | ||
| needs: [build, determine-environment] | ||
| environment: ${{ needs.determine-environment.outputs.environment }} | ||
|
|
||
| steps: | ||
| - name: Download build artifact | ||
| uses: actions/download-artifact@v4 | ||
| with: | ||
| name: build-output | ||
| path: build/ | ||
|
|
||
| - name: Install azcopy | ||
| run: | | ||
| wget -O azcopy.tar.gz https://aka.ms/downloadazcopy-v10-linux | ||
| tar -xf azcopy.tar.gz --strip-components=1 | ||
| sudo mv azcopy /usr/local/bin/ | ||
| azcopy --version | ||
| - name: Install Azure CLI | ||
| run: | | ||
| if ! command -v az &> /dev/null; then | ||
| curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash | ||
| fi | ||
| az version | ||
| - name: Upload to Azure Blob Storage with AzCopy and comprehensive MIME types | ||
| run: | | ||
| echo "Deploying to ${{ needs.determine-environment.outputs.environment }} environment" | ||
| echo "Starting high-performance sync of changed files with proper MIME types..." | ||
| # Create SAS token for azcopy (using account key) | ||
| end_date=$(date -u -d "30 minutes" '+%Y-%m-%dT%H:%MZ') | ||
| sas_token=$(az storage container generate-sas \ | ||
| --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} \ | ||
| --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} \ | ||
| --name '$web' \ | ||
| --permissions dlrw \ | ||
| --expiry $end_date \ | ||
| --output tsv) | ||
| azcopy sync "./build/" \ | ||
| "https://${{ secrets.STORAGE_ACCOUNT_NAME }}.blob.core.windows.net/\$web?$sas_token" \ | ||
| --delete-destination=true \ | ||
| --compare-hash=MD5 \ | ||
| --log-level=INFO \ | ||
| --cap-mbps=0 \ | ||
| --block-size-mb=4 | ||
| echo "Sync completed!" | ||
| - name: Set MIME types for all file types | ||
| run: | | ||
| echo "Setting MIME types for all file types..." | ||
| # Web files | ||
| echo "Setting MIME types for web files..." | ||
| az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.css" --content-type "text/css" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true | ||
| az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.js" --content-type "application/javascript" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true | ||
| az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.mjs" --content-type "application/javascript" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true | ||
| az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.json" --content-type "application/json" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true | ||
| az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.html" --content-type "text/html" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true | ||
| az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.htm" --content-type "text/html" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true | ||
| az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.xml" --content-type "application/xml" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true | ||
| az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.txt" --content-type "text/plain" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true | ||
| # Images | ||
| echo "Setting MIME types for images..." | ||
| az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.png" --content-type "image/png" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true | ||
| az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.jpg" --content-type "image/jpeg" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true | ||
| az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.jpeg" --content-type "image/jpeg" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true | ||
| az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.gif" --content-type "image/gif" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true | ||
| az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.webp" --content-type "image/webp" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true | ||
| az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.svg" --content-type "image/svg+xml" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true | ||
| az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.ico" --content-type "image/x-icon" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true | ||
| # Fonts | ||
| echo "Setting MIME types for fonts..." | ||
| az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.woff" --content-type "font/woff" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true | ||
| az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.woff2" --content-type "font/woff2" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true | ||
| az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.ttf" --content-type "font/ttf" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true | ||
| az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.otf" --content-type "font/otf" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true | ||
| echo "All MIME types set successfully!" | ||
| - name: Purge CDN endpoint (if configured) | ||
| run: | | ||
| if [[ -n "${{ secrets.CDN_ENDPOINT_NAME }}" ]] && [[ -n "${{ secrets.CDN_PROFILE_NAME }}" ]] && [[ -n "${{ secrets.CDN_RESOURCE_GROUP }}" ]]; then | ||
| echo "Note: CDN purge requires Azure login. Skipping CDN purge when using storage key authentication." | ||
| echo "To use CDN purge, you'll need to use Azure AD authentication or purge CDN manually." | ||
| else | ||
| echo "CDN configuration not found, skipping CDN purge." | ||
| fi | ||
| - name: Display deployment URL | ||
| run: | | ||
| echo "🚀 Deployment complete!" | ||
| echo "Environment: ${{ needs.determine-environment.outputs.environment }}" | ||
| echo "URL: https://${{ secrets.STORAGE_ACCOUNT_NAME }}.z13.web.core.windows.net" | ||
| if [[ -n "${{ secrets.CUSTOM_DOMAIN }}" ]]; then | ||
| echo "Custom Domain: ${{ secrets.CUSTOM_DOMAIN }}" | ||
| fi |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 3 months ago
To fix the reported issue, explicitly add a permissions: block to the deploy job in .github/workflows/build-and-deploy.yml. The job does not take any actions that require write permissions on the repository; it merely downloads artifacts, interacts with Azure, and displays output. As such, the least-privilege permissions for this job are contents: read, which allows the job to download artifacts but not modify repository contents. Add the following to the deploy job, just after runs-on: ubuntu-latest and before needs::
permissions:
contents: readThis mirrors the explicit permissions block in the build job and ensures compliance with least privilege recommendations.
-
Copy modified lines R102-R103
| @@ -99,6 +99,8 @@ | ||
|
|
||
| deploy: | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| needs: [build, determine-environment] | ||
| environment: ${{ needs.determine-environment.outputs.environment }} | ||
|
|
Main to dev merge