PageSourceSearch

https://azurecertprep.github.io/assets/js/6cf0b587.cf3a3297.js

js azurecertprep.github.io collected 2026-10-03 08:43:27 UTC 22,855 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunkazurecertprep=globalThis.webpackChunkazurecertprep||[]).push([[3580],{69243(e,n,s){s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>p,frontMatter:()=>r,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"az-400/03c-pipeline-fundamentals/challenge-19","title":"Challenge 19: GitHub Actions fundamentals","description":"This challenge focuses on GitHub Actions. Azure DevOps equivalents are noted where relevant.","source":"@site/docs/az-400/03c-pipeline-fundamentals/challenge-19.md","sourceDirName":"az-400/03c-pipeline-fundamentals","slug":"/az-400/03c-pipeline-fundamentals/challenge-19","permalink":"/docs/az-400/03c-pipeline-fundamentals/challenge-19","draft":false,"unlisted":false,"editUrl":"https://github.com/azurecertprep/azurecertprep.github.io/tree/main/docs/az-400/03c-pipeline-fundamentals/challenge-19.md","tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"sidebar_position":1,"title":"Challenge 19: GitHub Actions fundamentals"},"sidebar":"az400Sidebar","previous":{"title":"Challenge 18: Code coverage analysis","permalink":"/docs/az-400/03b-testing-pipelines/challenge-18"},"next":{"title":"Challenge 20: Azure Pipelines YAML","permalink":"/docs/az-400/03c-pipeline-fundamentals/challenge-20"}}');var i=s(74848),o=s(28453),a=s(67970);const r={sidebar_position:1,title:"Challenge 19: GitHub Actions fundamentals"},l="Challenge 19: GitHub Actions fundamentals",c={},d=[{value:"Exam skills mapped",id:"exam-skills-mapped",level:2},{value:"Scenario",id:"scenario",level:2},{value:"Task 1: Create the CI workflow with build and test stages",id:"task-1-create-the-ci-workflow-with-build-and-test-stages",level:2},{value:"Task 2: Add Docker build and push to GitHub Container Registry",id:"task-2-add-docker-build-and-push-to-github-container-registry",level:2},{value:"Task 3: Deploy to Azure App Service with staging and production",id:"task-3-deploy-to-azure-app-service-with-staging-and-production",level:2},{value:"Task 4: Create a composite action for reusable steps",id:"task-4-create-a-composite-action-for-reusable-steps",level:2},{value:"Task 5: Configure secrets and environment variables",id:"task-5-configure-secrets-and-environment-variables",level:2},{value:"Break & fix",id:"break--fix",level:2},{value:"Exercise 1: Fix the failing workflow",id:"exercise-1-fix-the-failing-workflow",level:3},{value:"Exercise 2: Debug the permissions issue",id:"exercise-2-debug-the-permissions-issue",level:3},{value:"Knowledge check",id:"knowledge-check",level:2},{value:"Cleanup",id:"cleanup",level:2}];function u(e){const n={admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components},{Details:s}=n;return s||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"challenge-19-github-actions-fundamentals",children:"Challenge 19: GitHub Actions fundamentals"})}),"\n",(0,i.jsx)(n.admonition,{title:"Platform: GitHub-first",type:"info",children:(0,i.jsx)(n.p,{children:"This challenge focuses on GitHub Actions. Azure DevOps equivalents are noted where relevant."})}),"\n",(0,i.jsx)(n.h2,{id:"exam-skills-mapped",children:"Exam skills mapped"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Select a deployment automation solution, including GitHub Actions"}),"\n",(0,i.jsx)(n.li,{children:"Develop pipelines by using YAML"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"scenario",children:"Scenario"}),"\n",(0,i.jsx)(n.p,{children:"Contoso Ltd is migrating their CI/CD pipelines from Jenkins to GitHub Actions. Their primary application is a Node.js REST API (Express.js) that is containerized and deployed to Azure App Service. The team needs a complete workflow that handles building, testing, container image creation, and staged deployments."}),"\n",(0,i.jsx)(n.p,{children:"The repository structure:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-text",children:"contoso-api/\n  src/\n    index.js\n    routes/\n    middleware/\n  tests/\n    unit/\n    integration/\n  Dockerfile\n  package.json\n  .github/\n    workflows/\n    actions/\n"})}
1),"\n",(0,i.jsx)(n.h2,{id:"task-1-create-the-ci-workflow-with-build-and-test-stages",children:"Task 1: Create the CI workflow with build and test stages"}),"\n",(0,i.jsxs)(n.p,{children:["Create ",(0,i.jsx)(n.code,{children:".github/workflows/ci-cd.yml"})," with triggers for push to ",(0,i.jsx)(n.code,{children:"main"})," and pull requests:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'name: Contoso API CI/CD\n\non:\n  push:\n    branches: [main]\n  pull_request:\n    branches: [main]\n  workflow_dispatch:\n    inputs:\n      environment:\n        description: "Target environment"\n        required: true\n        default: "staging"\n        type: choice\n        options:\n          - staging\n          - production\n      skip_tests:\n        description: "Skip test execution"\n        required: false\n        type: boolean\n        default: false\n\nenv:\n  NODE_VERSION: "20.x"\n  REGISTRY: ghcr.io\n  IMAGE_NAME: ${{ github.repository }}\n\njobs:\n  build:\n    name: Build and lint\n    runs-on: ubuntu-latest\n    outputs:\n      version: ${{ steps.version.outputs.version }}\n      sha_short: ${{ steps.version.outputs.sha_short }}\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n\n      - name: Set up Node.js\n        uses: actions/setup-node@v4\n        with:\n          node-version: ${{ env.NODE_VERSION }}\n          cache: "npm"\n\n      - name: Install dependencies\n        run: npm ci\n\n      - name: Run linter\n        run: npm run lint\n\n      - name: Generate version info\n        id: version\n        run: |\n          VERSION=$(node -p "require(\'./package.json\').version")\n          SHA_SHORT=$(git rev-parse --short HEAD)\n          echo "version=${VERSION}" >> $GITHUB_OUTPUT\n          echo "sha_short=${SHA_SHORT}" >> $GITHUB_OUTPUT\n\n      - name: Build application\n        run: npm run build\n\n      - name: Upload build artifact\n        uses: actions/upload-artifact@v4\n        with:\n          name: build-output\n          path: dist/\n          retention-days: 5\n\n  test:\n    name: Run tests\n    needs: build\n    runs-on: ubuntu-latest\n    if: ${{ !inputs.skip_tests }}\n    strategy:\n      matrix:\n        test-type: [unit, integration]\n    services:\n      redis:\n        image: redis:7-alpine\n        ports:\n          - 6379:6379\n        options: >-\n          --health-cmd "redis-cli ping"\n          --health-interval 10s\n          --health-timeout 5s\n          --health-retries 5\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n\n      - name: Set up Node.js\n        uses: actions/setup-node@v4\n        with:\n          node-version: ${{ env.NODE_VERSION }}\n          cache: "npm"\n\n      - name: Install dependencies\n        run: npm ci\n\n      - name: Run ${{ matrix.test-type }} tests\n        run: npm run test:${{ matrix.test-type }}\n        env:\n          REDIS_URL: redis://localhost:6379\n          CI: true\n\n      - name: Upload test results\n        if: always()\n        uses: actions/upload-artifact@v4\n        with:\n          name: test-results-${{ matrix.test-type }}\n          path: coverage/\n'})}),"\n",(0,i.jsx)(n.h2,{id:"task-2-add-docker-build-and-push-to-github-container-registry",children:"Task 2: Add Docker build and push to GitHub Container Registry"}),"\n",(0,i.jsx)(n.p,{children:"Add a job that builds and pushes the container image:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"  docker:\n    name: Build and push container image\n    needs: [build, test]\n    runs-on: ubuntu-latest\n    if: github.event_name == 'push' && github.ref == 'refs/heads/main'\n    permissions:\n      contents: read\n      packages: write\n    outputs:\n      image_tag: ${{ steps.meta.outputs.tags }}\n      image_digest: ${{ steps.push.outputs.digest }}\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n\n      - name: Set up Docker Buildx\n        uses: docker/setup-buildx-action@v3\n\n      - name: Log in to GitHub Container Registry\n        uses: docker/login-action@v3\n        with:\n          registry: ${{ env.REGISTRY }}\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Extract metadata for Docker\n        id: meta\n        uses: docker/metadata-action@v5\n        with:\n          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}\n          tags: |\n            type=sha,prefix=\n            type=semver,pattern={{version}},value=${{ needs.build.outputs.version }}\n            type=raw,value=latest,enable={{is_default_branch}}\n\n      - name: Build and push image\n        id: push\n        uses: docker/build-push-action@v5\n        with:\n          context: .\n          push: true\n          tags: ${{ steps.meta.outputs.tags }}\n          labels: ${{ steps.meta.outputs.labels }}\n          cache-from: type=gha\n          cache-to: type=gha,mode=max\n          build-args: |\n            NODE_VERSION=${{ env.NODE_VERSION }}\n            BUILD_SHA=${{ needs.build.outputs.sha_short }}\n"})}),"\n",(0,i.jsx)(n.h2,{id:"task-3-deploy-to-azure-app-service-with-staging-and-production",children:"Task 3: Deploy to Azure App Service with staging and production"}),"\n",(0,i.jsx)(n.p,{children:"Add deployment jobs using environments:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'  deploy-staging:\n    name: Deploy to staging\n    needs: docker\n    runs-on: ubuntu-latest\n    environment:\n      name: staging\n      url: https://contoso-api-staging.azurewebsites.net\n    steps:\n      - name: Log in to Azure\n        uses: azure/login@v2\n        with:\n          creds: ${{ secrets.AZURE_CREDENTIALS }}\n\n      - name: Deploy to Azure App Service (staging slot)\n        uses: azure/webapps-deploy@v3\n        with:\n          app-name: contoso-api\n          slot-name: staging\n          images: ${{ needs.docker.outputs.image_tag }}\n\n      - name: Run smoke tests against staging\n        run: |\n          for i in {1..10}; do\n            STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://contoso-api-staging.azurewebsites.net/health)\n            if [ "$STATUS" = "200" ]; then\n              echo "Staging is healthy"\n              exit 0\n            fi\n            echo "Attempt $i: Status $STATUS, retrying..."\n            sleep 10\n          done\n          echo "Staging health check failed"\n          exit 1\n\n  deploy-production:\n    name: Deploy to production\n    needs: deploy-staging\n    runs-on: ubuntu-latest\n    environment:\n      name: production\n      url: https://contoso-api.azurewebsites.net\n    steps:\n      - name: Log in to Azure\n        uses: azure/login@v2\n        with:\n          creds: ${{ secrets.AZURE_CREDENTIALS }}\n\n      - name: Swap staging slot to production\n        run: |\n          az webapp deployment slot swap \\\n            --resource-group contoso-rg \\\n            --name contoso-api \\\n            --slot staging \\\n            --target-slot production\n'})}),"\n",(0,i.jsx)(n.h2,{id:"task-4-create-a-composite-action-for-reusable-steps",children:"Task 4: Create a composite action for reusable steps"}),"\n",(0,i.jsxs)(n.p,{children:["Create ",(0,i.jsx)(n.code,{children:".github/actions/setup-node-project/action.yml"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'name: "Setup Node.js project"\ndescription: "Installs Node.js, caches depen
1dencies, and runs npm ci"\n\ninputs:\n  node-version:\n    description: "Node.js version to use"\n    required: false\n    default: "20.x"\n  working-directory:\n    description: "Working directory for npm commands"\n    required: false\n    default: "."\n\noutputs:\n  cache-hit:\n    description: "Whether npm cache was hit"\n    value: ${{ steps.cache.outputs[\'cache-hit\'] }}\n\nruns:\n  using: "composite"\n  steps:\n    - name: Set up Node.js ${{ inputs.node-version }}\n      uses: actions/setup-node@v4\n      with:\n        node-version: ${{ inputs.node-version }}\n\n    - name: Get npm cache directory\n      id: npm-cache-dir\n      shell: bash\n      run: echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT\n\n    - name: Cache npm dependencies\n      id: cache\n      uses: actions/cache@v4\n      with:\n        path: ${{ steps[\'npm-cache-dir\'].outputs.dir }}\n        key: ${{ runner.os }}-node-${{ inputs.node-version }}-${{ hashFiles(\'**/package-lock.json\') }}\n        restore-keys: |\n          ${{ runner.os }}-node-${{ inputs.node-version }}-\n\n    - name: Install dependencies\n      shell: bash\n      working-directory: ${{ inputs.working-directory }}\n      run: npm ci\n'})}),"\n",(0,i.jsx)(n.p,{children:"Use the composite action in the workflow:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"      - name: Setup project\n        uses: ./.github/actions/setup-node-project\n        with:\n          node-version: ${{ env.NODE_VERSION }}\n"})}),"\n",(0,i.jsx)(n.h2,{id:"task-5-configure-secrets-and-environment-variables",children:"Task 5: Configure secrets and environment variables"}),"\n",(0,i.jsx)(n.p,{children:"Configure the following secrets and variables at the repository and environment levels:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'# Repository secrets (available to all workflows)\ngh secret set AZURE_CREDENTIALS --body \'{"clientId":"...","clientSecret":"...","subscriptionId":"...","tenantId":"..."}\'\n\n# Environment-specific secrets\ngh secret set DB_CONNECTION_STRING --env staging --body "Server=staging-db.database.windows.net;..."\ngh secret set DB_CONNECTION_STRING --env production --body "Server=prod-db.database.windows.net;..."\n\n# Repository variables\ngh variable set APP_NAME --body "contoso-api"\ngh variable set AZURE_RESOURCE_GROUP --body "contoso-rg"\n\n# Environment variables\ngh variable set APP_SERVICE_PLAN --env staging --body "contoso-plan-staging"\ngh variable set APP_SERVICE_PLAN --env production --body "contoso-plan-prod"\n'})}),"\n",(0,i.jsx)(n.h2,{id:"break--fix",children:"Break & fix"}),"\n",(0,i.jsx)(n.h3,{id:"exercise-1-fix-the-failing-workflow",children:"Exercise 1: Fix the failing workflow"}),"\n",(0,i.jsx)(n.p,{children:"The following workflow has errors. Identify and fix them:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'name: Broken Workflow\n\non:\n  push:\n    branches: main    # ERROR 1: Should be an array [main]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Set output\n        run: echo "result=success" >> $GITHUB_OUTPUT  # ERROR 2: Missing id field\n\n      - name: Use output\n        run: echo ${{ steps.set-output.outputs.result }}  # ERROR 3: step id doesn\'t match\n\n  deploy:\n    needs: build\n    runs-on: ubuntu-latest\n    environment: production\n    steps:\n      - name: Deploy\n        uses: azure/webapps-deploy@v3\n        with:\n          app-name: ${{ env.APP_NAME }}  # ERROR 4: env context not available, use vars\n          images: ${{ needs.build.outputs.image }}  # ERROR 5: build job has no outputs defined\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Corrected version:"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"name: Fixed Workflow\n\non:\n  push:\n    branches: [main]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    outputs:\n      image: ${{ steps['set-output'].outputs.result }}\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Set output\n        id: set-output\n        run: echo \"result=success\" >> $GITHUB_OUTPUT\n\n      - name: Use output\n        run: echo ${{ steps['set-output'].outputs.result }}\n\n  deploy:\n    needs: build\n    runs-on: ubuntu-latest\n    environment: production\n    steps:\n      - name: Deploy\n        uses: azure/webapps-deploy@v3\n        with:\n          app-name: ${{ vars.APP_NAME }}\n          images: ${{ needs.build.outputs.image }}\n"})}),"\n",(0,i.jsx)(n.h3,{id:"exercise-2-debug-the-permissions-issue",children:"Exercise 2: Debug the permissions issue"}),"\n",(0,i.jsxs)(n.p,{children:["A workflow that pushes to GHCR fails with ",(0,i.jsx)(n.code,{children:"denied: permission_denied"}),". The workflow file contains:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"permissions:\n  contents: read\n"})}),"\n",(0,i.jsxs)(s,{children:[(0,i.jsx)("summary",{children:"Show solution"}),(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Fix:"})," Add ",(0,i.jsx)(n.code,{children:"packages: write"})," permission to allow pushing to GHCR:"]}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"permissions:\n  contents: read\n  packages: write\n"})})]}),"\n",(0,i.jsx)(n.h2,{id:"knowledge-check",children:"Knowledge check"}),"\n",(0,i.jsx)(a.A,{questions:[{question:"In GitHub Actions, what is the correct way to pass data between jobs?",options:["Use environment variables set with 'export'","Write to a shared file in the workspace","Use job outputs with '$GITHUB_OUTPUT' and the 'needs' context","Use repository variables as intermediary storage"],correctIndex:2,explanation:'Job outputs are defined using echo "key=value" >> $GITHUB_OUTPUT in a step with an id, declared in the job\'s outputs section, and consumed 
1in downstream jobs using ${{ needs.job_id.outputs.key }}. Environment variables and workspace files do not persist between jobs since each job runs on a fresh runner.'},{question:"Which trigger configuration allows manual workflow execution with custom parameters?",options:["'on: manual'","'on: workflow_dispatch' with 'inputs'","'on: repository_dispatch' with 'inputs'","'on: push' with 'if: github.event.manual'"],correctIndex:1,explanation:"workflow_dispatch allows manual triggering from the GitHub UI or API with typed inputs (string, boolean, choice, environment). repository_dispatch is triggered via the API with a client_payload but does not provide the same UI-driven input experience."},{question:"What is the primary advantage of a composite action over a reusable workflow?",options:["Composite actions can use secrets directly","Composite actions run in the same job, sharing the workspace and runner","Composite actions support matrix strategies","Composite actions can trigger other workflows"],correctIndex:1,explanation:"Composite actions run as steps within the calling job, meaning they share the same workspace, environment variables, and runner. Reusable workflows run as a separate job (or set of jobs) with their own runner instance. This makes composite actions better for grouping related steps that need shared state."},{question:"Which 'permissions' value is required for a workflow to push container images to GitHub Container Registry (ghcr.io)?",options:["'contents: write'","'packages: write'","'deployments: write'","'registry: write'"],correctIndex:1,explanation:"GHCR uses the packages permission scope. The workflow needs packages: write to push images and packages: read to pull them. When permissions is explicitly set, only the listed permissions are granted (principle of least privilege)."}]}),"\n",(0,i.jsx)(n.h2,{id:"cleanup",children:"Cleanup"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# Remove the test workflow runs (optional)\ngh run list --workflow=ci-cd.yml --limit 5 --json databaseId --jq '.[].databaseId' | \\\n  xargs -I {} gh run delete {}\n\n# Delete environment if no longer needed\ngh api --method DELETE repos/{owner}/{repo}/environments/staging\ngh api --method DELETE repos/{owner}/{repo}/environments/production\n\n# Remove GHCR images\ngh api --method DELETE /user/packages/container/contoso-api/versions/{version_id}\n"})})]})}function p(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}},67970(e,n,s){s.d(n,{A:()=>_});var t=s(96540);const i="container_Wc2S",o="question_w8BQ",a="questionText_khaT",r="questionNumber_tNAi",l="options_hoT3",c="option_h5Gz",d="correct_wiKw",u="incorrect_jk7n",p="dimmed_Rvup",h="optionLetter_SgXF",m="optionText_qkBQ",g="checkmark_PyUX",v="crossmark__CNH",b="explanationCorrect_PaNS",x="explanationIncorrect_Ul4c",w="scoreCard_qRIf",f="perfect_Nu3_",k="good_kzz1",j="review_WPHG";var y=s(74848);function _({questions:e}){const[n,s]=(0,t.useState)({}),o=Object.keys(n).length===e.length,a=Object.values(n).filter(Boolean).length,r=(e,n)=>{s(s=>({...s,[e]:n}))};return(0,y.jsxs)("div",{className:i,children:[e.map((e,n)=>(0,y.jsx)(E,{index:n,question:e.question,options:e.options,correctIndex:e.correctAnswer??e.correctIndex,explanation:e.explanation,onAnswer:r},n)),o&&(0,y.jsxs)("div",{className:w,children:[(0,y.jsxs)("strong",{children:["Score: ",a,"/",e.length]}),a===e.length?(0,y.jsx)("span",{className:f,children:" \u2014 Perfect!"}):a>=.75*e.length?(0,y.jsx)("span",{className:k,children:" \u2014 Good job!"}):(0,y.jsx)("span",{className:j,children:" \u2014 Review the explanations above."})]})]})}function E({index:e,question:n,options:s,correctIndex:i,explanation:w,onAnswer:f}){const[k,j]=(0,t.useState)(null),[_,E]=(0,t.useState)(!1);return(0,y.jsxs)("div",{className:o,children:[(0,y.jsxs)("p",{className:a,children:[(0,y.jsxs)("span",{className:r,children:[e+1,"."]})," ",n]}),(0,y.jsx)("div",{className:l,children:s.map((n,s)=>{let t=c;return _&&(t+=s===i?" "+d:s===k?" "+u:" "+p),(0,y.jsxs)("button",{className:t,onClick:()=>(n=>{_||(j(n),E(!0),f(e,n===i))})(s),disabled:_,children:[(0,y.jsx)("span",{className:h,children:String.fromCharCode(65+s)}),(0,y.jsx)("span",{className:m,children:n}),_&&s===i&&(0,y.jsx)("span",{className:g,children:"\u2713"}),_&&s===k&&s!==i&&(0,y.jsx)("span",{className:v,children:"\u2717"})]},s)})}),_&&(0,y.jsxs)("div",{className:k===i?b:x,children:[(0,y.jsx)("strong",{children:k===i?"Correct!":"Incorrect."})," ",w]})]})}},28453(e,n,s){s.d(n,{R:()=>a,x:()=>r});var t=s(96540);const i={},o=t.createContext(i);function a(e){const n=t.useContext(o);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.