name: Update GitHub Languages
on:
workflow_dispatch:
inputs:
dry-run:
description: Run the workflow without creating a pull request
required: false
default: false
type: boolean
schedule:
- cron: "0 0 * * *"
jobs:
update-github-languages:
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: write
pull-requests: write
models: read
environment:
name: huginn
deployment: false
if: github.repository == 'luxass/github-languages-rs'
steps:
- name: generate token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 id: app-token
with:
repositories: luxass/github-languages-rs
client-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
permission-contents: write
permission-pull-requests: write
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with:
persist-credentials: false
- name: turn yaml to json (old)
id: old-languages-json
uses: mikefarah/yq@0f4fb8d35ec1a939d78dd6862f494d19ec589f19 with:
cmd: yq -p yaml -o json languages.yml > languages.json
- name: old github languages
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 id: old-github-languages
with:
script: |
const { generateOldLanguages } = await import('${{ github.workspace }}/.github/scripts/update-languages.mjs')
await generateOldLanguages({ github, context, core })
- name: download github languages
run: |
curl -sSL https://raw.githubusercontent.com/github/linguist/master/lib/linguist/languages.yml -o languages.yml
- name: turn yaml to json
id: languages-json
uses: mikefarah/yq@0f4fb8d35ec1a939d78dd6862f494d19ec589f19 with:
cmd: yq -p yaml -o json languages.yml > languages.json
- name: build
run: cargo build
- name: generate diff
id: generate-diff
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 with:
script: |
const { generateDiff } = await import('${{ github.workspace }}/.github/scripts/update-languages.mjs')
await generateDiff({ github, context, core })
- name: generate pr metadata (ai)
id: pr-metadata
if: ${{ steps.generate-diff.outputs.DIFF != '' && github.event.inputs.dry-run != 'true' }}
env:
PR_METADATA_URL: ${{ vars.PR_METADATA_URL }}
PR_METADATA_HMAC_SECRET: ${{ secrets.PR_METADATA_HMAC_SECRET }}
REPOSITORY: ${{ github.repository }}
PR_METADATA_CONTEXT: |
This repository syncs GitHub Linguist language metadata into generated Rust sources.
Prefer the most specific changed language name as the scope when there is a clear single target.
Use "feat" when languages are added, "chore" when languages are removed or metadata is updated, and "fix" when an incorrect value is corrected.
run: |
set -euo pipefail
DIFF_CONTENT=$(cat languages.diff)
REQUEST_JSON=$(jq -n \
--arg repository "$REPOSITORY" \
--arg context "$PR_METADATA_CONTEXT" \
--arg diff "$DIFF_CONTENT" \
'{
repository: $repository,
context: $context,
diff: $diff
}')
TIMESTAMP=$(( $(date +%s) * 1000 ))
SIGNATURE=$(printf '%s' "${TIMESTAMP}.${REQUEST_JSON}" | openssl dgst -sha256 -hmac "$PR_METADATA_HMAC_SECRET" -hex | awk '{print $2}')
RESPONSE=$(printf '%s' "$REQUEST_JSON" | curl -fsS -X POST "$PR_METADATA_URL" \
-H "Content-Type: application/json" \
-H "User-Agent: luxass/github-languages-rs (+https://github.com/luxass/github-languages-rs; workflow=update.yaml)" \
-H "X-Timestamp: $TIMESTAMP" \
-H "X-Signature: $SIGNATURE" \
--data-binary @-)
echo "API response: $RESPONSE"
TYPE=$(echo "$RESPONSE" | jq -r '.type')
SCOPE=$(echo "$RESPONSE" | jq -r '.scope')
MESSAGE=$(echo "$RESPONSE" | jq -r '.message')
BODY=$(echo "$RESPONSE" | jq -r '.body')
TITLE="$TYPE${SCOPE:+($SCOPE)}: $MESSAGE"
echo "✅ Generated PR title: $TITLE"
{
echo "title<<GITHUB_EOF"
printf '%s' "$TITLE"
echo
echo "GITHUB_EOF"
} >> "$GITHUB_OUTPUT"
{
echo "body<<GITHUB_EOF"
printf '%s' "$BODY"
echo
echo "GITHUB_EOF"
} >> "$GITHUB_OUTPUT"
- name: prepare pr body
id: pr-body
if: ${{ github.event.inputs.dry-run != 'true' }}
env:
NEW_LANGUAGES: ${{ steps.generate-diff.outputs.result-new-languages }}
REMOVED_LANGUAGES: ${{ steps.generate-diff.outputs.result-removed-languages }}
MODIFIED_LANGUAGES: ${{ steps.generate-diff.outputs.result-modified-languages }}
run: |
set -euo pipefail
BODY=$(cat <<EOF
I found some new changes in GitHub's Linguist Repository.
I don't know what they changed, but I'm sure it's important.
If you want you can go take a look yourself.
${NEW_LANGUAGES}
${REMOVED_LANGUAGES}
${MODIFIED_LANGUAGES}
I will be waiting for your approval 🤖.
This is an automated PR to update GitHub Languages.
EOF
)
{
echo "body<<GITHUB_EOF"
printf '%s\n' "$BODY"
echo "GITHUB_EOF"
} >> "$GITHUB_OUTPUT"
- name: create pull request
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 if: ${{ github.event.inputs.dry-run != 'true' }}
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
COMMIT_MESSAGE: "${{ steps.pr-metadata.outputs.title || 'feat: updated github languages' }}"
with:
token: ${{ steps.app-token.outputs.token }}
commit-message: ${{ env.COMMIT_MESSAGE }}
title: ${{ env.COMMIT_MESSAGE }}
body: ${{ steps.pr-body.outputs.body }}
committer: huginn-watch[bot] <273299945+huginn-watch[bot]@users.noreply.github.com>
author: huginn-watch[bot] <273299945+huginn-watch[bot]@users.noreply.github.com>
branch: update-github-languages
add-paths: languages.yml,src/generated.rs
base: main
reviewers: luxass