GitHub Actions YAML 작성 - Azure OIDC 로그인 설정 - VS Code Marketplace 자동화 게시까지
1. Github actons YAML 작성 (위치: .github/workflows/marketplace.yml)
선택한 게시 브랜치의 소스를 패키징해 단일 VSIX로 게시할 때,
name: VS Code Marketplace
on:
workflow_dispatch:
inputs:
operation:
description: "identity: ID 조회 / verify: 권한 확인 / publish: 실제 게시"
required: true
default: verify
type: choice
options:
- identity
- verify
- publish
permissions:
contents: read
id-token: write
# 같은 저장소에서 게시 작업이 동시에 실행되지 않게 합니다.
concurrency:
group: vscode-marketplace-${{ github.repository }}
cancel-in-progress: false
env:
# [교체: 게시 브랜치] 예: main
PUBLISH_BRANCH: "[교체: 게시 브랜치]"
# [교체: 확장 디렉터리] 예: apps/vscode-extension 또는 .
EXTENSION_DIR: "[교체: 확장 디렉터리]"
# [교체: Marketplace publisher ID] 예: frillab
MARKETPLACE_PUBLISHER: "[교체: Marketplace publisher ID]"
NODE_VERSION: "22"
jobs:
marketplace:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Validate execution branch
env:
WORKFLOW_REF: ${{ github.ref }}
shell: bash
run: |
set -euo pipefail
expected_ref="refs/heads/${PUBLISH_BRANCH}"
if [[ "$WORKFLOW_REF" != "$expected_ref" ]]; then
echo "::error::Run this workflow from ${PUBLISH_BRANCH}."
exit 1
fi
- name: Check out source
if: inputs.operation != 'identity'
uses: actions/checkout@v7
- name: Set up Node.js
if: inputs.operation != 'identity'
uses: actions/setup-node@v7
with:
node-version: ${{ env.NODE_VERSION }}
- name: Install extension dependencies
if: inputs.operation != 'identity'
working-directory: ${{ env.EXTENSION_DIR }}
run: npm ci
- name: Validate extension publisher
if: inputs.operation != 'identity'
working-directory: ${{ env.EXTENSION_DIR }}
shell: bash
run: |
set -euo pipefail
node <<'NODE'
const manifest = require("./package.json");
const expected = process.env.MARKETPLACE_PUBLISHER;
if (manifest.publisher !== expected) {
console.error(
`Publisher mismatch: package.json=${manifest.publisher}, expected=${expected}`
);
process.exit(1);
}
console.log(
`Extension: ${manifest.publisher}.${manifest.name}@${manifest.version}`
);
NODE
- name: Sign in to Azure using GitHub OIDC
uses: azure/login@v3
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Get Marketplace identity ID
if: inputs.operation == 'identity'
shell: bash
run: |
set -euo pipefail
az rest \
--method GET \
--url https://app.vssps.visualstudio.com/_apis/profile/profiles/me \
--resource 499b84ac-1321-427f-aa17-267ca6975798 \
--query id \
--output tsv
- name: Verify Marketplace publisher access
if: inputs.operation != 'identity'
working-directory: ${{ env.EXTENSION_DIR }}
env:
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
run: |
npx --no-install vsce verify-pat \
"$MARKETPLACE_PUBLISHER" \
--azure-credential
- name: Package extension
if: inputs.operation == 'publish'
working-directory: ${{ env.EXTENSION_DIR }}
run: |
npx --no-install vsce package \
--out marketplace-extension.vsix
- name: Publish extension
if: inputs.operation == 'publish'
working-directory: ${{ env.EXTENSION_DIR }}
env:
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
run: |
npx --no-install vsce publish \
--azure-credential \
--packagePath marketplace-extension.vsix
2. 확장 프로젝트 준비 확인 (@vscode/vsce를 개발 의존성이 있어야 합니다.)
확장 프로그램 디렉토리에서 실행!
npm install --save-dev @vscode/vsce
package.json의 publisher ID도 맞춰야합니다.
# package.json
{
"publisher": "[교체: Marketplace publisher ID]"
}
3. Azure Portal 등록
Microsoft Azure
portal.azure.com
1) Azure Portal 로그인 (https://portal.azure.com/)
2) 관리 ID (Managed Identities) -> 만들기 (Create)

- Subscription (구독): 사용할 Azure 구독
- Resource group (리소스 그룹): 새로 만들기 -> "[교체!: 프로젝트 명]-publishing"
- Name: [교체!: 프로젝트 명]-marketplace
- Region (지역): 선택 가능한 지역
Review + create (검토 + 만들기) 클릭 -> Create (만들기) 클릭
3) ID 기록 해두기 (클라이언트 ID, 구독 ID, 테넌트 ID)

생성한 관리 ID의 Overview / 개요에서 배포 정보 -> 리소스 선택

- Client ID (클라이언트 ID)
- Subscription ID (구독 ID)
- Tenant ID (테넌트 ID): 없을 경우 Microsoft Entra ID -> Overview -> Tenant ID

4) Azure Reader (독자) 권한 부여
Access control (IAM) (엑세스 제어 (IAM)) -> Add (추가) → Add role assignment (역할 할당 추가)



- Role (역할): Reader (독자)
- Assign access to (다음에 대한 엑세스 할당): Managed identity (관리 ID)
- Select members (+ 구성원 선택): 방금 만든 [교체! 프로젝트 명]-marketplace
- 하단 Review + assign (검토 + 할당) 클릭
5) Github와 관리 ID 연결
Settings (설정) -> Federated credentials (페더레이션된 자격 증명) -> Add credential (자격 증명 추가)


- Issuer (발급자 URL): https://token.actions.githubusercontent.com
- Organization (조직): 조직 이름

- Organization ID (조직 ID): https://api.github.com/orgs/[교체! 조직 이름]
- Repository (리포지토리): 저장소 이름
- Repository ID (리포지토리 ID): https://api.github.com/orgs/[교체! 조직 이름]/repos
- Ctrl(commend) + F 로 "조직 이름/저장소 이름" 검색
{
"id": 아이디!!,
"node_id": "노드아이디",
"name": "저장소 이름",
"full_name": "조직 이름/저장소 이름",
...
...
}
- Entity type (엔티티): Branch (분기)
- Branch (분기): main
- Subject identifier (주체 식별자, 같은 형식인지 확인!): repo:[교체! 조직 이름]/[교체! 프로젝트 명]:ref:refs/heads/main
- 🆗: repo:test/test:ref:refs/heads/main
- ❌: repo:test@조직ID/test@프로젝트ID:ref:refs/heads/main
- Credential name: github-[교체! 프로젝트 명]-main
- Audience (대상 그룹): api://AzureADTokenExchange
- Add (추가) 클릭
4. Github secrets 등록 (3-3에서 기록해 둔 Tenant ID, Client ID, Subscription ID 등록)
해당 Repo -> Settings -> Secrets and Variables -> Actions -> New repository secret

- AZURE_CLIENT_ID: 관리 ID의 Client ID
- AZURE_TENANT_ID: 해당 Azure 디렉터리의 Tenant ID
- AZURE_SUBSCRIPTION_ID: 관리 ID가 속한 Subscription ID
Client Secret이나 VSCE_PAT을 새로 만들 필요는 없습니다.
5. Marketplace 등록용 ID 조회 (위치: github/workflows/marketplace-identity-check.yml)
1) 준비 사항 / 유의 사항
- GitHub secrets의 AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_SUBSCRIPTION_ID
- 해당 관리 ID에 등록한 연합 자격 증명의 Subject (Azure의 Subject는 저장소마다 맞춰야 합니다.)
repo:[교체: 소유자]/[교체: 저장소]:ref:refs/heads/[교체: 브랜치]
- 실행 브랜치가 main이 아니라면 브랜치 검사와 오류 문구 수정
2) marketplace-identity-check.yml 작성
marketplace-identity-check.yml 작성 후 -> main 병합 -> workflow 실행
name: Check Marketplace Identity
on:
workflow_dispatch:
permissions:
contents: read
id-token: write
jobs:
check:
runs-on: ubuntu-latest
steps:
- name: Require main
env:
WORKFLOW_REF: ${{ github.ref }}
run: |
if [ "$WORKFLOW_REF" != "refs/heads/main" ]; then
echo "::error::Run this workflow from main."
exit 1
fi
- name: Sign in to Azure
uses: azure/login@v3
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Get Marketplace identity ID
run: |
az rest \
--method GET \
--url https://app.vssps.visualstudio.com/_apis/profile/profiles/me \
--resource 499b84ac-1321-427f-aa17-267ca6975798 \
--query id \
--output tsv
3) Actions에서 Marketplace identity ID 얻기

숫자로 시작하는 Marketplace identity ID만 저장
6. publisher(package.json에 적은 publisher)에 구성원 추가
Visual Studio Marketplace
Extensions for Visual Studio family of products on Visual Studio Marketplace
marketplace.visualstudio.com
1) Visual Studio Marketplace (https://marketplace.visualstudio.com/)

2) + Create Publisher
Package.json에 적은 Publisher 이름과 동일해야함.

3) + New extension (VISX 파일을 드래그 엔 드롭)

4) Members (구성원 관리) -> 추가 (Add) -> User name: Marketplace identity ID (Role: Contributeor) -> 저장

7. 권한 확인 후 게시 (1번에 작성한 워크플로우를 실행 실패할 경우 Actions 확인)
'Deployment > GitHub' 카테고리의 다른 글
| 실제로 사용하는 Git 명령어 (0) | 2026.05.25 |
|---|---|
| Github Actions (1) | 2026.05.05 |
| Learn Git Branching (2) remote (0) | 2026.05.01 |
| GitHub Skills (0) | 2026.04.30 |
| Learn Git Branching (1) main (0) | 2026.04.30 |