[{"data":1,"prerenderedAt":1580},["ShallowReactive",2],{"navigation_docs":3,"-engineering-github-workflows":209,"-engineering-github-workflows-surround":1575},[4,8,50,75,133,149,162,171,205],{"title":5,"path":6,"stem":7},"Introduction","\u002Fintroduction","0.introduction",{"title":9,"path":10,"stem":11,"children":12,"page":49},"Company","\u002Fcompany","1.company",[13,17,21,25,29,33,37,41,45],{"title":14,"path":15,"stem":16},"About","\u002Fcompany\u002Fabout","1.company\u002F0.about",{"title":18,"path":19,"stem":20},"Values","\u002Fcompany\u002Fvalues","1.company\u002F1.values",{"title":22,"path":23,"stem":24},"Communication","\u002Fcompany\u002Fcommunication","1.company\u002Fcommunication",{"title":26,"path":27,"stem":28},"Competition","\u002Fcompany\u002Fcompetition","1.company\u002Fcompetition",{"title":30,"path":31,"stem":32},"Hybrid Working","\u002Fcompany\u002Fhybrid-working","1.company\u002Fhybrid-working",{"title":34,"path":35,"stem":36},"Operations","\u002Fcompany\u002Foperations","1.company\u002Foperations",{"title":38,"path":39,"stem":40},"Policies","\u002Fcompany\u002Fpolicies","1.company\u002Fpolicies",{"title":42,"path":43,"stem":44},"Product","\u002Fcompany\u002Fproduct","1.company\u002Fproduct",{"title":46,"path":47,"stem":48},"Security","\u002Fcompany\u002Fsecurity","1.company\u002Fsecurity",false,{"title":51,"path":52,"stem":53,"children":54,"page":49},"People Ops","\u002Fpeople-ops","2.people-ops",[55,59,63,67,71],{"title":56,"path":57,"stem":58},"Compensation","\u002Fpeople-ops\u002Fcompensation","2.people-ops\u002Fcompensation",{"title":60,"path":61,"stem":62},"Education","\u002Fpeople-ops\u002Feducation","2.people-ops\u002Feducation",{"title":64,"path":65,"stem":66},"Expenses","\u002Fpeople-ops\u002Fexpenses","2.people-ops\u002Fexpenses",{"title":68,"path":69,"stem":70},"Holiday & Leave","\u002Fpeople-ops\u002Fleave","2.people-ops\u002Fleave",{"title":72,"path":73,"stem":74},"Onboarding","\u002Fpeople-ops\u002Fonboarding","2.people-ops\u002Fonboarding",{"title":76,"path":77,"stem":78,"children":79,"page":49},"Engineering","\u002Fengineering","3.engineering",[80,84,88,92,96,117,121,125,129],{"title":81,"path":82,"stem":83},"Development Setup","\u002Fengineering\u002Fdevelopment-setup","3.engineering\u002F1.development-setup",{"title":85,"path":86,"stem":87},"Contributing","\u002Fengineering\u002Fcontributing","3.engineering\u002Fcontributing",{"title":89,"path":90,"stem":91},"Production Database","\u002Fengineering\u002Fdatabase-connection","3.engineering\u002Fdatabase-connection",{"title":93,"path":94,"stem":95},"Deployment","\u002Fengineering\u002Fdeployment","3.engineering\u002Fdeployment",{"title":97,"path":98,"stem":99,"children":100,"page":49},"Github","\u002Fengineering\u002Fgithub","3.engineering\u002Fgithub",[101,105,109,113],{"title":102,"path":103,"stem":104},"Packages","\u002Fengineering\u002Fgithub\u002Fpackages","3.engineering\u002Fgithub\u002Fpackages",{"title":106,"path":107,"stem":108},"Personal Access Token","\u002Fengineering\u002Fgithub\u002Fpersonal-access-token","3.engineering\u002Fgithub\u002Fpersonal-access-token",{"title":110,"path":111,"stem":112},"Troubleshooting","\u002Fengineering\u002Fgithub\u002Ftroubleshooting","3.engineering\u002Fgithub\u002Ftroubleshooting",{"title":114,"path":115,"stem":116},"Workflows","\u002Fengineering\u002Fgithub\u002Fworkflows","3.engineering\u002Fgithub\u002Fworkflows",{"title":118,"path":119,"stem":120},"Platform Ops","\u002Fengineering\u002Fplatform-ops","3.engineering\u002Fplatform-ops",{"title":122,"path":123,"stem":124},"Project Management","\u002Fengineering\u002Fproject-management","3.engineering\u002Fproject-management",{"title":126,"path":127,"stem":128},"Releases","\u002Fengineering\u002Frelease","3.engineering\u002Frelease",{"title":130,"path":131,"stem":132},"Tools","\u002Fengineering\u002Ftools","3.engineering\u002Ftools",{"title":134,"path":135,"stem":136,"children":137,"page":49},"Design","\u002Fdesign","4.design",[138,142,146],{"title":139,"path":140,"stem":141},"Branding","\u002Fdesign\u002Fbranding","4.design\u002Fbranding",{"title":143,"path":144,"stem":145},"Design Thinking","\u002Fdesign\u002Fdesign-thinking","4.design\u002Fdesign-thinking",{"title":130,"path":147,"stem":148},"\u002Fdesign\u002Ftools","4.design\u002Ftools",{"title":150,"path":151,"stem":152,"children":153,"page":49},"Sales","\u002Fsales","4.sales",[154,158],{"title":155,"path":156,"stem":157},"Customer Onboarding","\u002Fsales\u002Fonboarding","4.sales\u002Fonboarding",{"title":159,"path":160,"stem":161},"Sales Tools","\u002Fsales\u002Ftools","4.sales\u002Ftools",{"title":163,"path":164,"stem":165,"children":166,"page":49},"Marketing","\u002Fmarketing","5.marketing",[167],{"title":168,"path":169,"stem":170},"Messaging","\u002Fmarketing\u002Fmessaging","5.marketing\u002Fmessaging",{"title":172,"path":173,"stem":174,"children":175,"page":49},"Data Ops","\u002Fdata-ops","6.data-ops",[176,185,189,193,197,201],{"title":177,"path":178,"stem":179,"children":180,"page":49},"Capability Exchange","\u002Fdata-ops\u002Fcapability-exchange","6.data-ops\u002FCapability Exchange",[181],{"title":182,"path":183,"stem":184},"Leaderboard Calculation","\u002Fdata-ops\u002Fcapability-exchange\u002Fleaderboard-calculation","6.data-ops\u002FCapability Exchange\u002Fleaderboard-calculation",{"title":186,"path":187,"stem":188},"Account Portal (CAS)","\u002Fdata-ops\u002Faccount-portal","6.data-ops\u002Faccount-portal",{"title":190,"path":191,"stem":192},"Adding Products","\u002Fdata-ops\u002Faddin-products","6.data-ops\u002Faddin-products",{"title":194,"path":195,"stem":196},"Adding Vendors","\u002Fdata-ops\u002Fadding-vendors","6.data-ops\u002Fadding-vendors",{"title":198,"path":199,"stem":200},"Message Queues","\u002Fdata-ops\u002Fmessage-queues","6.data-ops\u002Fmessage-queues",{"title":202,"path":203,"stem":204},"Refreshing Vendors","\u002Fdata-ops\u002Frefreshing-vendors","6.data-ops\u002Frefreshing-vendors",{"title":206,"path":207,"stem":208},"Glossary","\u002Fglossary","glossary",{"id":210,"title":114,"body":211,"description":1569,"extension":1570,"links":1571,"meta":1572,"navigation":281,"path":115,"seo":1573,"stem":116,"__hash__":1574},"docs\u002F3.engineering\u002Fgithub\u002Fworkflows.md",{"type":212,"value":213,"toc":1561},"minimark",[214,219,228,235,240,250,411,414,418,423,431,1318,1322,1329,1526,1528,1530,1534,1549,1557],[215,216,218],"h2",{"id":217},"centralised-workflows","Centralised workflows",[220,221,222,223,227],"p",{},"We can define reusable GitHub Actions workflows in a central repository and call them from multiple repositories using ",[224,225,226],"code",{},"workflow_call",".",[220,229,230,231,234],{},"At ESProfiler, these shared workflows live in ",[224,232,233],{},"ES-Profiler\u002F.github-private"," and are consumed from project repositories to keep automation consistent and avoid duplicated workflow logic.",[236,237,239],"h4",{"id":238},"calling-a-shared-workflow","Calling a Shared Workflow",[220,241,242,243,245,246,249],{},"In any repository within the ESProfiler organisation, you can call a centrally defined workflow. These workflows must be stored in the ",[224,244,233],{}," repository. This example shows how to call the ",[224,247,248],{},"mark-released-items-done"," workflow:",[251,252,257],"pre",{"className":253,"code":254,"language":255,"meta":256,"style":256},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","name: Mark released issues as 'Done'\n\non:\n  release:\n    types: [published]\n\njobs:\n  call-shared-workflow:\n    uses: ES-Profiler\u002F.github-private\u002F.github\u002Fworkflows\u002Fmark-released-items-done.yml@main\n    secrets: inherit\n    permissions:\n      contents: read\n      pull-requests: read\n      issues: write\n      repository-projects: write\n","yaml","",[224,258,259,276,283,293,301,318,323,331,339,350,361,369,380,390,401],{"__ignoreMap":256},[260,261,264,268,272],"span",{"class":262,"line":263},"line",1,[260,265,267],{"class":266},"swJcz","name",[260,269,271],{"class":270},"sMK4o",":",[260,273,275],{"class":274},"sfazB"," Mark released issues as 'Done'\n",[260,277,279],{"class":262,"line":278},2,[260,280,282],{"emptyLinePlaceholder":281},true,"\n",[260,284,286,290],{"class":262,"line":285},3,[260,287,289],{"class":288},"sfNiH","on",[260,291,292],{"class":270},":\n",[260,294,296,299],{"class":262,"line":295},4,[260,297,298],{"class":266},"  release",[260,300,292],{"class":270},[260,302,304,307,309,312,315],{"class":262,"line":303},5,[260,305,306],{"class":266},"    types",[260,308,271],{"class":270},[260,310,311],{"class":270}," [",[260,313,314],{"class":274},"published",[260,316,317],{"class":270},"]\n",[260,319,321],{"class":262,"line":320},6,[260,322,282],{"emptyLinePlaceholder":281},[260,324,326,329],{"class":262,"line":325},7,[260,327,328],{"class":266},"jobs",[260,330,292],{"class":270},[260,332,334,337],{"class":262,"line":333},8,[260,335,336],{"class":266},"  call-shared-workflow",[260,338,292],{"class":270},[260,340,342,345,347],{"class":262,"line":341},9,[260,343,344],{"class":266},"    uses",[260,346,271],{"class":270},[260,348,349],{"class":274}," ES-Profiler\u002F.github-private\u002F.github\u002Fworkflows\u002Fmark-released-items-done.yml@main\n",[260,351,353,356,358],{"class":262,"line":352},10,[260,354,355],{"class":266},"    secrets",[260,357,271],{"class":270},[260,359,360],{"class":274}," inherit\n",[260,362,364,367],{"class":262,"line":363},11,[260,365,366],{"class":266},"    permissions",[260,368,292],{"class":270},[260,370,372,375,377],{"class":262,"line":371},12,[260,373,374],{"class":266},"      contents",[260,376,271],{"class":270},[260,378,379],{"class":274}," read\n",[260,381,383,386,388],{"class":262,"line":382},13,[260,384,385],{"class":266},"      pull-requests",[260,387,271],{"class":270},[260,389,379],{"class":274},[260,391,393,396,398],{"class":262,"line":392},14,[260,394,395],{"class":266},"      issues",[260,397,271],{"class":270},[260,399,400],{"class":274}," write\n",[260,402,404,407,409],{"class":262,"line":403},15,[260,405,406],{"class":266},"      repository-projects",[260,408,271],{"class":270},[260,410,400],{"class":274},[412,413],"hr",{},[215,415,417],{"id":416},"example-workflows","Example Workflows",[419,420,422],"h3",{"id":421},"marking-released-items-as-done","Marking released items as \"Done\"",[220,424,425,426,430],{},"This workflow finds pull requests referenced in release notes, discovers the issues those PRs close, updates their project status to ",[427,428,429],"strong",{},"Done",", and comments on each issue with a link back to the published release.",[251,432,434],{"className":253,"code":433,"language":255,"meta":256,"style":256},"name: Mark released issues as 'Done'\n\non:\n  workflow_call:\n\njobs:\n  update-issues:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n      pull-requests: read\n      issues: write\n      repository-projects: write\n    steps:\n      - name: Update project status for issues in this release\n        uses: actions\u002Fgithub-script@v8\n        with:\n          github-token: ${{ secrets.PROJECT_V2_TOKEN || secrets.GITHUB_TOKEN }}\n          script: |\n            const owner = context.repo.owner;\n            const repo = context.repo.repo;\n            const release = context.payload.release;\n\n            \u002F\u002F Your IDs\n            const PROJECT_ID = '\u003Cinsert ID>';\n            const STATUS_FIELD_ID = '\u003Cinsert ID>';\n            const DONE_OPTION_ID = '\u003Cinsert ID>';\n\n            const releaseUrl = release.html_url;\n            const body = release.body || '';\n\n            \u002F\u002F Collect PR numbers mentioned in the release body: \"#123\" or \"pull\u002F123\"\n            const prNumbers = [...body.matchAll(\u002F(?:#|pull\\\u002F)(\\d+)\u002Fg)]\n              .map(m => parseInt(m[1], 10))\n              .filter((n, i, arr) => arr.indexOf(n) === i);\n\n            console.log('PRs found in release notes:', prNumbers);\n\n            const gql = (query, variables) => github.graphql(query, variables);\n\n            for (const prNumber of prNumbers) {\n              console.log(`Processing PR #${prNumber}`);\n\n              \u002F\u002F 1) Get issues that PR closes\n              const prData = await gql(\n                `\n                query($owner: String!, $repo: String!, $pr: Int!) {\n                  repository(owner: $owner, name: $repo) {\n                    pullRequest(number: $pr) {\n                      closingIssuesReferences(first: 50) {\n                        nodes {\n                          id\n                          number\n                          title\n                        }\n                      }\n                    }\n                  }\n                }\n                `,\n                { owner, repo, pr: prNumber }\n              );\n\n              const issues =\n                prData.repository.pullRequest?.closingIssuesReferences?.nodes || [];\n\n              if (!issues.length) {\n                console.log(`No closing issues for PR #${prNumber}`);\n                continue;\n              }\n\n              for (const issue of issues) {\n                console.log(`Updating project status for issue #${issue.number}`);\n\n                \u002F\u002F 2) Find the ProjectV2 item for this issue on your project\n                const itemData = await gql(\n                  `\n                  query($projectId: ID!, $issueSearch: String!) {\n                    node(id: $projectId) {\n                      ... on ProjectV2 {\n                        items(first: 50, query: $issueSearch) {\n                          nodes {\n                            id\n                            content {\n                              ... on Issue {\n                                id\n                              }\n                            }\n                          }\n                        }\n                      }\n                    }\n                  }\n                  `,\n                  { projectId: PROJECT_ID, issueSearch: `${issue.number}` }\n                );\n\n                const items = itemData.node?.items?.nodes || [];\n                const projectItem = items.find(\n                  (it) => it.content && it.content.id === issue.id\n                );\n\n                if (!projectItem) {\n                  console.log(`No project item found for issue #${issue.number}`);\n                  continue;\n                }\n\n                const itemId = projectItem.id;\n\n                \u002F\u002F 3) Set Status = Done\n                await gql(\n                  `\n                  mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $optionId: String!) {\n                    updateProjectV2ItemFieldValue(\n                      input: {\n                        projectId: $projectId\n                        itemId: $itemId\n                        fieldId: $fieldId\n                        value: { singleSelectOptionId: $optionId }\n                      }\n                    ) {\n                      projectV2Item { id }\n                    }\n                  }\n                  `,\n                  {\n                    projectId: PROJECT_ID,\n                    itemId,\n                    fieldId: STATUS_FIELD_ID,\n                    optionId: DONE_OPTION_ID,\n                  }\n                );\n\n                console.log(\n                  `Issue #${issue.number} status moved to Done (release ${release.tag_name})`\n                );\n\n                \u002F\u002F 4) Add a comment linking back to this release\n                await github.rest.issues.createComment({\n                  owner,\n                  repo,\n                  issue_number: issue.number,\n                  body: `Marked as **Done** when release [${release.tag_name}](${releaseUrl}) was published (includes PR #${prNumber}).`\n                });\n              }\n            }\n",[224,435,436,444,448,454,461,465,471,478,488,494,502,510,518,526,533,546,557,565,576,588,594,600,606,611,617,623,629,635,640,646,652,657,663,669,675,681,686,692,697,703,708,714,720,725,731,737,743,749,755,761,767,773,779,785,791,797,803,809,815,821,827,833,839,844,850,856,861,867,873,879,885,890,896,902,907,913,919,925,931,937,943,949,955,961,967,973,979,985,991,997,1002,1007,1012,1017,1023,1029,1035,1040,1046,1052,1058,1063,1068,1074,1080,1086,1091,1096,1102,1107,1113,1119,1124,1130,1136,1142,1148,1154,1160,1166,1171,1177,1183,1188,1193,1198,1204,1210,1216,1222,1228,1233,1238,1243,1249,1255,1260,1265,1271,1277,1283,1289,1295,1301,1307,1312],{"__ignoreMap":256},[260,437,438,440,442],{"class":262,"line":263},[260,439,267],{"class":266},[260,441,271],{"class":270},[260,443,275],{"class":274},[260,445,446],{"class":262,"line":278},[260,447,282],{"emptyLinePlaceholder":281},[260,449,450,452],{"class":262,"line":285},[260,451,289],{"class":288},[260,453,292],{"class":270},[260,455,456,459],{"class":262,"line":295},[260,457,458],{"class":266},"  workflow_call",[260,460,292],{"class":270},[260,462,463],{"class":262,"line":303},[260,464,282],{"emptyLinePlaceholder":281},[260,466,467,469],{"class":262,"line":320},[260,468,328],{"class":266},[260,470,292],{"class":270},[260,472,473,476],{"class":262,"line":325},[260,474,475],{"class":266},"  update-issues",[260,477,292],{"class":270},[260,479,480,483,485],{"class":262,"line":333},[260,481,482],{"class":266},"    runs-on",[260,484,271],{"class":270},[260,486,487],{"class":274}," ubuntu-latest\n",[260,489,490,492],{"class":262,"line":341},[260,491,366],{"class":266},[260,493,292],{"class":270},[260,495,496,498,500],{"class":262,"line":352},[260,497,374],{"class":266},[260,499,271],{"class":270},[260,501,379],{"class":274},[260,503,504,506,508],{"class":262,"line":363},[260,505,385],{"class":266},[260,507,271],{"class":270},[260,509,379],{"class":274},[260,511,512,514,516],{"class":262,"line":371},[260,513,395],{"class":266},[260,515,271],{"class":270},[260,517,400],{"class":274},[260,519,520,522,524],{"class":262,"line":382},[260,521,406],{"class":266},[260,523,271],{"class":270},[260,525,400],{"class":274},[260,527,528,531],{"class":262,"line":392},[260,529,530],{"class":266},"    steps",[260,532,292],{"class":270},[260,534,535,538,541,543],{"class":262,"line":403},[260,536,537],{"class":270},"      -",[260,539,540],{"class":266}," name",[260,542,271],{"class":270},[260,544,545],{"class":274}," Update project status for issues in this release\n",[260,547,549,552,554],{"class":262,"line":548},16,[260,550,551],{"class":266},"        uses",[260,553,271],{"class":270},[260,555,556],{"class":274}," actions\u002Fgithub-script@v8\n",[260,558,560,563],{"class":262,"line":559},17,[260,561,562],{"class":266},"        with",[260,564,292],{"class":270},[260,566,568,571,573],{"class":262,"line":567},18,[260,569,570],{"class":266},"          github-token",[260,572,271],{"class":270},[260,574,575],{"class":274}," ${{ secrets.PROJECT_V2_TOKEN || secrets.GITHUB_TOKEN }}\n",[260,577,579,582,584],{"class":262,"line":578},19,[260,580,581],{"class":266},"          script",[260,583,271],{"class":270},[260,585,587],{"class":586},"s7zQu"," |\n",[260,589,591],{"class":262,"line":590},20,[260,592,593],{"class":274},"            const owner = context.repo.owner;\n",[260,595,597],{"class":262,"line":596},21,[260,598,599],{"class":274},"            const repo = context.repo.repo;\n",[260,601,603],{"class":262,"line":602},22,[260,604,605],{"class":274},"            const release = context.payload.release;\n",[260,607,609],{"class":262,"line":608},23,[260,610,282],{"emptyLinePlaceholder":281},[260,612,614],{"class":262,"line":613},24,[260,615,616],{"class":274},"            \u002F\u002F Your IDs\n",[260,618,620],{"class":262,"line":619},25,[260,621,622],{"class":274},"            const PROJECT_ID = '\u003Cinsert ID>';\n",[260,624,626],{"class":262,"line":625},26,[260,627,628],{"class":274},"            const STATUS_FIELD_ID = '\u003Cinsert ID>';\n",[260,630,632],{"class":262,"line":631},27,[260,633,634],{"class":274},"            const DONE_OPTION_ID = '\u003Cinsert ID>';\n",[260,636,638],{"class":262,"line":637},28,[260,639,282],{"emptyLinePlaceholder":281},[260,641,643],{"class":262,"line":642},29,[260,644,645],{"class":274},"            const releaseUrl = release.html_url;\n",[260,647,649],{"class":262,"line":648},30,[260,650,651],{"class":274},"            const body = release.body || '';\n",[260,653,655],{"class":262,"line":654},31,[260,656,282],{"emptyLinePlaceholder":281},[260,658,660],{"class":262,"line":659},32,[260,661,662],{"class":274},"            \u002F\u002F Collect PR numbers mentioned in the release body: \"#123\" or \"pull\u002F123\"\n",[260,664,666],{"class":262,"line":665},33,[260,667,668],{"class":274},"            const prNumbers = [...body.matchAll(\u002F(?:#|pull\\\u002F)(\\d+)\u002Fg)]\n",[260,670,672],{"class":262,"line":671},34,[260,673,674],{"class":274},"              .map(m => parseInt(m[1], 10))\n",[260,676,678],{"class":262,"line":677},35,[260,679,680],{"class":274},"              .filter((n, i, arr) => arr.indexOf(n) === i);\n",[260,682,684],{"class":262,"line":683},36,[260,685,282],{"emptyLinePlaceholder":281},[260,687,689],{"class":262,"line":688},37,[260,690,691],{"class":274},"            console.log('PRs found in release notes:', prNumbers);\n",[260,693,695],{"class":262,"line":694},38,[260,696,282],{"emptyLinePlaceholder":281},[260,698,700],{"class":262,"line":699},39,[260,701,702],{"class":274},"            const gql = (query, variables) => github.graphql(query, variables);\n",[260,704,706],{"class":262,"line":705},40,[260,707,282],{"emptyLinePlaceholder":281},[260,709,711],{"class":262,"line":710},41,[260,712,713],{"class":274},"            for (const prNumber of prNumbers) {\n",[260,715,717],{"class":262,"line":716},42,[260,718,719],{"class":274},"              console.log(`Processing PR #${prNumber}`);\n",[260,721,723],{"class":262,"line":722},43,[260,724,282],{"emptyLinePlaceholder":281},[260,726,728],{"class":262,"line":727},44,[260,729,730],{"class":274},"              \u002F\u002F 1) Get issues that PR closes\n",[260,732,734],{"class":262,"line":733},45,[260,735,736],{"class":274},"              const prData = await gql(\n",[260,738,740],{"class":262,"line":739},46,[260,741,742],{"class":274},"                `\n",[260,744,746],{"class":262,"line":745},47,[260,747,748],{"class":274},"                query($owner: String!, $repo: String!, $pr: Int!) {\n",[260,750,752],{"class":262,"line":751},48,[260,753,754],{"class":274},"                  repository(owner: $owner, name: $repo) {\n",[260,756,758],{"class":262,"line":757},49,[260,759,760],{"class":274},"                    pullRequest(number: $pr) {\n",[260,762,764],{"class":262,"line":763},50,[260,765,766],{"class":274},"                      closingIssuesReferences(first: 50) {\n",[260,768,770],{"class":262,"line":769},51,[260,771,772],{"class":274},"                        nodes {\n",[260,774,776],{"class":262,"line":775},52,[260,777,778],{"class":274},"                          id\n",[260,780,782],{"class":262,"line":781},53,[260,783,784],{"class":274},"                          number\n",[260,786,788],{"class":262,"line":787},54,[260,789,790],{"class":274},"                          title\n",[260,792,794],{"class":262,"line":793},55,[260,795,796],{"class":274},"                        }\n",[260,798,800],{"class":262,"line":799},56,[260,801,802],{"class":274},"                      }\n",[260,804,806],{"class":262,"line":805},57,[260,807,808],{"class":274},"                    }\n",[260,810,812],{"class":262,"line":811},58,[260,813,814],{"class":274},"                  }\n",[260,816,818],{"class":262,"line":817},59,[260,819,820],{"class":274},"                }\n",[260,822,824],{"class":262,"line":823},60,[260,825,826],{"class":274},"                `,\n",[260,828,830],{"class":262,"line":829},61,[260,831,832],{"class":274},"                { owner, repo, pr: prNumber }\n",[260,834,836],{"class":262,"line":835},62,[260,837,838],{"class":274},"              );\n",[260,840,842],{"class":262,"line":841},63,[260,843,282],{"emptyLinePlaceholder":281},[260,845,847],{"class":262,"line":846},64,[260,848,849],{"class":274},"              const issues =\n",[260,851,853],{"class":262,"line":852},65,[260,854,855],{"class":274},"                prData.repository.pullRequest?.closingIssuesReferences?.nodes || [];\n",[260,857,859],{"class":262,"line":858},66,[260,860,282],{"emptyLinePlaceholder":281},[260,862,864],{"class":262,"line":863},67,[260,865,866],{"class":274},"              if (!issues.length) {\n",[260,868,870],{"class":262,"line":869},68,[260,871,872],{"class":274},"                console.log(`No closing issues for PR #${prNumber}`);\n",[260,874,876],{"class":262,"line":875},69,[260,877,878],{"class":274},"                continue;\n",[260,880,882],{"class":262,"line":881},70,[260,883,884],{"class":274},"              }\n",[260,886,888],{"class":262,"line":887},71,[260,889,282],{"emptyLinePlaceholder":281},[260,891,893],{"class":262,"line":892},72,[260,894,895],{"class":274},"              for (const issue of issues) {\n",[260,897,899],{"class":262,"line":898},73,[260,900,901],{"class":274},"                console.log(`Updating project status for issue #${issue.number}`);\n",[260,903,905],{"class":262,"line":904},74,[260,906,282],{"emptyLinePlaceholder":281},[260,908,910],{"class":262,"line":909},75,[260,911,912],{"class":274},"                \u002F\u002F 2) Find the ProjectV2 item for this issue on your project\n",[260,914,916],{"class":262,"line":915},76,[260,917,918],{"class":274},"                const itemData = await gql(\n",[260,920,922],{"class":262,"line":921},77,[260,923,924],{"class":274},"                  `\n",[260,926,928],{"class":262,"line":927},78,[260,929,930],{"class":274},"                  query($projectId: ID!, $issueSearch: String!) {\n",[260,932,934],{"class":262,"line":933},79,[260,935,936],{"class":274},"                    node(id: $projectId) {\n",[260,938,940],{"class":262,"line":939},80,[260,941,942],{"class":274},"                      ... on ProjectV2 {\n",[260,944,946],{"class":262,"line":945},81,[260,947,948],{"class":274},"                        items(first: 50, query: $issueSearch) {\n",[260,950,952],{"class":262,"line":951},82,[260,953,954],{"class":274},"                          nodes {\n",[260,956,958],{"class":262,"line":957},83,[260,959,960],{"class":274},"                            id\n",[260,962,964],{"class":262,"line":963},84,[260,965,966],{"class":274},"                            content {\n",[260,968,970],{"class":262,"line":969},85,[260,971,972],{"class":274},"                              ... on Issue {\n",[260,974,976],{"class":262,"line":975},86,[260,977,978],{"class":274},"                                id\n",[260,980,982],{"class":262,"line":981},87,[260,983,984],{"class":274},"                              }\n",[260,986,988],{"class":262,"line":987},88,[260,989,990],{"class":274},"                            }\n",[260,992,994],{"class":262,"line":993},89,[260,995,996],{"class":274},"                          }\n",[260,998,1000],{"class":262,"line":999},90,[260,1001,796],{"class":274},[260,1003,1005],{"class":262,"line":1004},91,[260,1006,802],{"class":274},[260,1008,1010],{"class":262,"line":1009},92,[260,1011,808],{"class":274},[260,1013,1015],{"class":262,"line":1014},93,[260,1016,814],{"class":274},[260,1018,1020],{"class":262,"line":1019},94,[260,1021,1022],{"class":274},"                  `,\n",[260,1024,1026],{"class":262,"line":1025},95,[260,1027,1028],{"class":274},"                  { projectId: PROJECT_ID, issueSearch: `${issue.number}` }\n",[260,1030,1032],{"class":262,"line":1031},96,[260,1033,1034],{"class":274},"                );\n",[260,1036,1038],{"class":262,"line":1037},97,[260,1039,282],{"emptyLinePlaceholder":281},[260,1041,1043],{"class":262,"line":1042},98,[260,1044,1045],{"class":274},"                const items = itemData.node?.items?.nodes || [];\n",[260,1047,1049],{"class":262,"line":1048},99,[260,1050,1051],{"class":274},"                const projectItem = items.find(\n",[260,1053,1055],{"class":262,"line":1054},100,[260,1056,1057],{"class":274},"                  (it) => it.content && it.content.id === issue.id\n",[260,1059,1061],{"class":262,"line":1060},101,[260,1062,1034],{"class":274},[260,1064,1066],{"class":262,"line":1065},102,[260,1067,282],{"emptyLinePlaceholder":281},[260,1069,1071],{"class":262,"line":1070},103,[260,1072,1073],{"class":274},"                if (!projectItem) {\n",[260,1075,1077],{"class":262,"line":1076},104,[260,1078,1079],{"class":274},"                  console.log(`No project item found for issue #${issue.number}`);\n",[260,1081,1083],{"class":262,"line":1082},105,[260,1084,1085],{"class":274},"                  continue;\n",[260,1087,1089],{"class":262,"line":1088},106,[260,1090,820],{"class":274},[260,1092,1094],{"class":262,"line":1093},107,[260,1095,282],{"emptyLinePlaceholder":281},[260,1097,1099],{"class":262,"line":1098},108,[260,1100,1101],{"class":274},"                const itemId = projectItem.id;\n",[260,1103,1105],{"class":262,"line":1104},109,[260,1106,282],{"emptyLinePlaceholder":281},[260,1108,1110],{"class":262,"line":1109},110,[260,1111,1112],{"class":274},"                \u002F\u002F 3) Set Status = Done\n",[260,1114,1116],{"class":262,"line":1115},111,[260,1117,1118],{"class":274},"                await gql(\n",[260,1120,1122],{"class":262,"line":1121},112,[260,1123,924],{"class":274},[260,1125,1127],{"class":262,"line":1126},113,[260,1128,1129],{"class":274},"                  mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $optionId: String!) {\n",[260,1131,1133],{"class":262,"line":1132},114,[260,1134,1135],{"class":274},"                    updateProjectV2ItemFieldValue(\n",[260,1137,1139],{"class":262,"line":1138},115,[260,1140,1141],{"class":274},"                      input: {\n",[260,1143,1145],{"class":262,"line":1144},116,[260,1146,1147],{"class":274},"                        projectId: $projectId\n",[260,1149,1151],{"class":262,"line":1150},117,[260,1152,1153],{"class":274},"                        itemId: $itemId\n",[260,1155,1157],{"class":262,"line":1156},118,[260,1158,1159],{"class":274},"                        fieldId: $fieldId\n",[260,1161,1163],{"class":262,"line":1162},119,[260,1164,1165],{"class":274},"                        value: { singleSelectOptionId: $optionId }\n",[260,1167,1169],{"class":262,"line":1168},120,[260,1170,802],{"class":274},[260,1172,1174],{"class":262,"line":1173},121,[260,1175,1176],{"class":274},"                    ) {\n",[260,1178,1180],{"class":262,"line":1179},122,[260,1181,1182],{"class":274},"                      projectV2Item { id }\n",[260,1184,1186],{"class":262,"line":1185},123,[260,1187,808],{"class":274},[260,1189,1191],{"class":262,"line":1190},124,[260,1192,814],{"class":274},[260,1194,1196],{"class":262,"line":1195},125,[260,1197,1022],{"class":274},[260,1199,1201],{"class":262,"line":1200},126,[260,1202,1203],{"class":274},"                  {\n",[260,1205,1207],{"class":262,"line":1206},127,[260,1208,1209],{"class":274},"                    projectId: PROJECT_ID,\n",[260,1211,1213],{"class":262,"line":1212},128,[260,1214,1215],{"class":274},"                    itemId,\n",[260,1217,1219],{"class":262,"line":1218},129,[260,1220,1221],{"class":274},"                    fieldId: STATUS_FIELD_ID,\n",[260,1223,1225],{"class":262,"line":1224},130,[260,1226,1227],{"class":274},"                    optionId: DONE_OPTION_ID,\n",[260,1229,1231],{"class":262,"line":1230},131,[260,1232,814],{"class":274},[260,1234,1236],{"class":262,"line":1235},132,[260,1237,1034],{"class":274},[260,1239,1241],{"class":262,"line":1240},133,[260,1242,282],{"emptyLinePlaceholder":281},[260,1244,1246],{"class":262,"line":1245},134,[260,1247,1248],{"class":274},"                console.log(\n",[260,1250,1252],{"class":262,"line":1251},135,[260,1253,1254],{"class":274},"                  `Issue #${issue.number} status moved to Done (release ${release.tag_name})`\n",[260,1256,1258],{"class":262,"line":1257},136,[260,1259,1034],{"class":274},[260,1261,1263],{"class":262,"line":1262},137,[260,1264,282],{"emptyLinePlaceholder":281},[260,1266,1268],{"class":262,"line":1267},138,[260,1269,1270],{"class":274},"                \u002F\u002F 4) Add a comment linking back to this release\n",[260,1272,1274],{"class":262,"line":1273},139,[260,1275,1276],{"class":274},"                await github.rest.issues.createComment({\n",[260,1278,1280],{"class":262,"line":1279},140,[260,1281,1282],{"class":274},"                  owner,\n",[260,1284,1286],{"class":262,"line":1285},141,[260,1287,1288],{"class":274},"                  repo,\n",[260,1290,1292],{"class":262,"line":1291},142,[260,1293,1294],{"class":274},"                  issue_number: issue.number,\n",[260,1296,1298],{"class":262,"line":1297},143,[260,1299,1300],{"class":274},"                  body: `Marked as **Done** when release [${release.tag_name}](${releaseUrl}) was published (includes PR #${prNumber}).`\n",[260,1302,1304],{"class":262,"line":1303},144,[260,1305,1306],{"class":274},"                });\n",[260,1308,1310],{"class":262,"line":1309},145,[260,1311,884],{"class":274},[260,1313,1315],{"class":262,"line":1314},146,[260,1316,1317],{"class":274},"            }\n",[419,1319,1321],{"id":1320},"handling-new-issues-added-to-a-repo","Handling new issues added to a repo",[220,1323,1324,1325,1328],{},"This workflow applies the ",[224,1326,1327],{},"Needs Triage"," label to newly opened issues and adds them to the Development Board.",[251,1330,1332],{"className":253,"code":1331,"language":255,"meta":256,"style":256},"name: Process New Issues\n\non:\n  workflow_call:\n\njobs:\n  label_issues:\n    runs-on: ubuntu-latest\n    permissions:\n      issues: write\n    steps:\n      - name: Add 'Needs Triage' label\n        run: |\n          curl -X POST \\\n            -H \"Accept: application\u002Fvnd.github+json\" \\\n            -H \"Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}\" \\\n            -H \"X-GitHub-Api-Version: 2022-11-28\" \\\n            https:\u002F\u002Fapi.github.com\u002Frepos\u002F${{ github.repository }}\u002Fissues\u002F${{ github.event.issue.number }}\u002Flabels \\\n            -d '{\"labels\":[\"Needs Triage\"]}'\n  add-to-dev-project:\n    name: Add issue to dev project\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\u002Fadd-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2\n        with:\n          project-url: https:\u002F\u002Fgithub.com\u002Forgs\u002FES-Profiler\u002Fprojects\u002F2\n          github-token: ${{ secrets.ADD_TO_PROJECT_PAT }}\n",[224,1333,1334,1343,1347,1353,1359,1363,1369,1376,1384,1390,1398,1404,1415,1424,1429,1434,1439,1444,1449,1454,1461,1471,1479,1485,1501,1507,1517],{"__ignoreMap":256},[260,1335,1336,1338,1340],{"class":262,"line":263},[260,1337,267],{"class":266},[260,1339,271],{"class":270},[260,1341,1342],{"class":274}," Process New Issues\n",[260,1344,1345],{"class":262,"line":278},[260,1346,282],{"emptyLinePlaceholder":281},[260,1348,1349,1351],{"class":262,"line":285},[260,1350,289],{"class":288},[260,1352,292],{"class":270},[260,1354,1355,1357],{"class":262,"line":295},[260,1356,458],{"class":266},[260,1358,292],{"class":270},[260,1360,1361],{"class":262,"line":303},[260,1362,282],{"emptyLinePlaceholder":281},[260,1364,1365,1367],{"class":262,"line":320},[260,1366,328],{"class":266},[260,1368,292],{"class":270},[260,1370,1371,1374],{"class":262,"line":325},[260,1372,1373],{"class":266},"  label_issues",[260,1375,292],{"class":270},[260,1377,1378,1380,1382],{"class":262,"line":333},[260,1379,482],{"class":266},[260,1381,271],{"class":270},[260,1383,487],{"class":274},[260,1385,1386,1388],{"class":262,"line":341},[260,1387,366],{"class":266},[260,1389,292],{"class":270},[260,1391,1392,1394,1396],{"class":262,"line":352},[260,1393,395],{"class":266},[260,1395,271],{"class":270},[260,1397,400],{"class":274},[260,1399,1400,1402],{"class":262,"line":363},[260,1401,530],{"class":266},[260,1403,292],{"class":270},[260,1405,1406,1408,1410,1412],{"class":262,"line":371},[260,1407,537],{"class":270},[260,1409,540],{"class":266},[260,1411,271],{"class":270},[260,1413,1414],{"class":274}," Add 'Needs Triage' label\n",[260,1416,1417,1420,1422],{"class":262,"line":382},[260,1418,1419],{"class":266},"        run",[260,1421,271],{"class":270},[260,1423,587],{"class":586},[260,1425,1426],{"class":262,"line":392},[260,1427,1428],{"class":274},"          curl -X POST \\\n",[260,1430,1431],{"class":262,"line":403},[260,1432,1433],{"class":274},"            -H \"Accept: application\u002Fvnd.github+json\" \\\n",[260,1435,1436],{"class":262,"line":548},[260,1437,1438],{"class":274},"            -H \"Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}\" \\\n",[260,1440,1441],{"class":262,"line":559},[260,1442,1443],{"class":274},"            -H \"X-GitHub-Api-Version: 2022-11-28\" \\\n",[260,1445,1446],{"class":262,"line":567},[260,1447,1448],{"class":274},"            https:\u002F\u002Fapi.github.com\u002Frepos\u002F${{ github.repository }}\u002Fissues\u002F${{ github.event.issue.number }}\u002Flabels \\\n",[260,1450,1451],{"class":262,"line":578},[260,1452,1453],{"class":274},"            -d '{\"labels\":[\"Needs Triage\"]}'\n",[260,1455,1456,1459],{"class":262,"line":590},[260,1457,1458],{"class":266},"  add-to-dev-project",[260,1460,292],{"class":270},[260,1462,1463,1466,1468],{"class":262,"line":596},[260,1464,1465],{"class":266},"    name",[260,1467,271],{"class":270},[260,1469,1470],{"class":274}," Add issue to dev project\n",[260,1472,1473,1475,1477],{"class":262,"line":602},[260,1474,482],{"class":266},[260,1476,271],{"class":270},[260,1478,487],{"class":274},[260,1480,1481,1483],{"class":262,"line":608},[260,1482,530],{"class":266},[260,1484,292],{"class":270},[260,1486,1487,1489,1492,1494,1497],{"class":262,"line":613},[260,1488,537],{"class":270},[260,1490,1491],{"class":266}," uses",[260,1493,271],{"class":270},[260,1495,1496],{"class":274}," actions\u002Fadd-to-project@244f685bbc3b7adfa8466e08b698b5577571133e",[260,1498,1500],{"class":1499},"sHwdD"," # v1.0.2\n",[260,1502,1503,1505],{"class":262,"line":619},[260,1504,562],{"class":266},[260,1506,292],{"class":270},[260,1508,1509,1512,1514],{"class":262,"line":625},[260,1510,1511],{"class":266},"          project-url",[260,1513,271],{"class":270},[260,1515,1516],{"class":274}," https:\u002F\u002Fgithub.com\u002Forgs\u002FES-Profiler\u002Fprojects\u002F2\n",[260,1518,1519,1521,1523],{"class":262,"line":631},[260,1520,570],{"class":266},[260,1522,271],{"class":270},[260,1524,1525],{"class":274}," ${{ secrets.ADD_TO_PROJECT_PAT }}\n",[412,1527],{},[412,1529],{},[215,1531,1533],{"id":1532},"important-token-requirements-for-project-access","Important: token requirements for project access",[220,1535,1536,1537,1540,1541,1544,1545,1548],{},"For GitHub Project operations in centralised workflows, you will typically need a PAT secret (for example, ",[224,1538,1539],{},"PROJECT_V2_TOKEN"," or ",[224,1542,1543],{},"ADD_TO_PROJECT_PAT",") because ",[224,1546,1547],{},"GITHUB_TOKEN"," may not have the required project-level access across repositories.",[220,1550,1551,1552,227],{},"Use a fine-grained PAT with the minimum required permissions and store it in repository or organisation secrets. For setup instructions, see ",[1553,1554,1556],"a",{"href":1555},".\u002Fpersonal-access-token#how-to-create-a-fine-grained-token","How to create a fine-grained token",[1558,1559,1560],"style",{},"html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":256,"searchDepth":278,"depth":278,"links":1562},[1563,1564,1568],{"id":217,"depth":278,"text":218},{"id":416,"depth":278,"text":417,"children":1565},[1566,1567],{"id":421,"depth":285,"text":422},{"id":1320,"depth":285,"text":1321},{"id":1532,"depth":278,"text":1533},"Reusable and centralised GitHub Actions workflows used across ESProfiler repositories.","md",null,{},{"title":114,"description":1569},"E4qxEMz5znQKgohVNYt7ZfkC9PSJZxVxMvmOY6GGfT4",[1576,1578],{"title":110,"path":111,"stem":112,"description":1577,"children":-1},"Troubleshooting guide for GitHub issues.",{"title":118,"path":119,"stem":120,"description":1579,"children":-1},"Eveyrthing you need to know about observability of ESProfiler, as well as reporting and handling issues as they arise with infrastructure and hosting.",1778263962233]