What is Hackers' Pub?

Hackers' Pub is a place for software engineers to share their knowledge and experience with each other. It's also an ActivityPub-enabled social network, so you can follow your favorite hackers in the fediverse and get their latest posts in your feed.

A coworker and I were both in bands when we were younger and havenโ€™t played in a while, so we both agreed to learn Anthem by Rush and play the next time Iโ€™m in town. On our first phone call check in our comments were โ€œitโ€™s faster with more time changes than I rememberedโ€ ๐Ÿ˜€

youtu.be/3oEQuzHp5I0

0
0
0
0

A coworker and I were both in bands when we were younger and havenโ€™t played in a while, so we both agreed to learn Anthem by Rush and play the next time Iโ€™m in town. On our first phone call check in our comments were โ€œitโ€™s faster with more time changes than I rememberedโ€ ๐Ÿ˜€

youtu.be/3oEQuzHp5I0

0
0
0
0
0
0
2
0
0
0
0
0
0
0
0
0
0
0
รšvod do MeshCore

Odolnรก sรญลฅ, kterรก nezรกvisรญ na Internetu a mobilnรญch operรกtorech a dokรกลพe pล™enรกลกet zprรกvy pล™es celou republiku? Ano, je to moลพnรฉ. Tohle zvlรกdne Meshcore, kterรฝ uลพ mฤ›sรญc objevuji. A protoลพe jsem musel v zaฤรกtcรญch hodnฤ› vฤ›cรญ zjistit a vyzkouลกet sรกm, rozhodl jsem se, ลพe napรญลกu takovรฝ รบvod do tรฉto sรญtฤ›, kde se dozvรญte, jak funguje a jak se do nรญ pล™ipojit a jak ji prakticky pouลพรญvat. Hodit se to mลฏลพe nejen tomu, kdo by si to rรกd opravdu zkusil, ale uลพiteฤnรฉ to mลฏลพe bรฝt i pro ty, kteล™รญ si jen chtฤ›jรญ rozลกรญล™it obzory a vฤ›dฤ›t, jak tyhle sรญtฤ› fungujรญ.

https://blog.eischmann.cz/2026/02/15/uvod-do-meshcore/ (reakce na tento pล™รญspฤ›vek se mลฏลพe zobrazit jako komentรกล™ pod ฤlรกnkem)
0
2
0
0
0
0
1
0
0
0
0
1
1
0
0
0
0

decentralized data hosting idea

incomplete thought but I feel like something that would be useful is having a portable sense of digital identity where apps could, with consent, read and write data to to a kind of namespaced portion of your identity storage. that way all of your data lives with you.

the closest thing we have to portable digital identity is email which is unfortunate because it is trash technology, but trying to play the hand we were dealt I wonder if we could have applications start a thread in your inbox that represents your state, your data storage with the application. every time they need to commit something new they just respond to the thread, with an attachment or something.

logging into the application I guess would involve forwarding that thread to some email address on the application side? so that they get the attachments and they can rebuild your state on their end. close to a magic link login. that way your data only needs to exist in memory while you are using it and the application servers you do not need to persist it.

kind of falls apart as I think through it idk

0

My RSS feed goes back approx. 1 year, mostly because I don't want to overwhelm new subscribers to the point where they just "mark all as read" because they can't be bothered to go through.

Posts also work well in "reader mode" in browsers so it should be ok for most people.

Today I was thinking that it might be a bad idea and that I should put all the old posts back in my feed.

Then I subscribed to a feed with 100+ posts...aaaaand.. clicked "mark all as read".

Well 10-20 posts it is then.

0
์บก์ณ๋ณด๋“œ์ชฝ ๋ณด๊ณ ์žˆ๋Š”๋ฐ
์™œ DP ํฌํŠธ๊ฐ€ ๋‹ฌ๋ฆฐ ์บก์ณ๋ณด๋“œ๋Š” ์—†์ง€?
๋ฐฉ์†กํ•˜๋Š”์‚ฌ๋žŒ๋“ค ์„ค๋งˆ ์ „๋ถ€ DP ๊ฐ€ ์•„๋‹ˆ๋ผ HDMI ๋กœ ์—ฐ๊ฒฐํ•ด์„œ ํ•˜๊ณ ์žˆ๋Š”๊ฑฐ์•ผ?
์š”์ฆ˜ ๊ทธ๋ž˜ํ”ฝ์นด๋“œ DP3๊ฐœ HDMI ํ•œ๊ฐœ๊ฐ€ ๋Œ€๋ถ€๋ถ„์ธ๋ฐ ๋Œ€์ฒด ์–ด๋–ป๊ฒŒ์—ฐ๊ฒฐํ•˜๋Š”๊ฑฐ์•ผ ???
0
0
0
0

The XY Problem is commonly described as wanting to use X to solve Y, and then asking how to X, without also mentioning that you want to solve Y.

And the Inverse XY Problem is when you think someone else should use X to solve Y, so you suggest X without confirming that they *want* to solve Y in the first place.

The Inverse XY problem is common in tech evangelism and sales of all kinds.

0
0
0
0

Leider reiht sich die SPD in die populistische Forderung ein, Social-Media fรผr Kinder/Jugendliche zu verbieten/einzuschrรคnken. Damit erweist sie dem Jugendschutz einen Bรคrendienst & stรคrkt BigTech.

Verstehe nicht, warum die Partei Expert:innen nicht einbindet. Da war sie schon mal deutlich weiter.

Positionspapier
SPD fordert Social-Media-Verbot fรผr Kinder unter
14
Stand: 15.02.2026 15:30 Uhr
Lรคnder wie Australien oder Frankreich haben bereits gesetzliche Regelungen. In Deutschland ringt die Politik noch um den richtigen Umgang mit sozialen Medien fรผr Minderjรคhrige. Nun gibt es von der SPD einen konkreten Vorschlag.
0

๐Ÿค– An AI agent created a GitHub account 2 weeks ago.

Itโ€™s already landed PRs in major projects and is cold-emailing maintainers to offer its services.

Maintainers donโ€™t seem to know itโ€™s an agent and the code is getting merged.

Weโ€™re in new territory! ๐Ÿค 

socket.dev/blog/ai-agent-lands

0
0
1
0
0
0

๊ทธ๋ ‡๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋Ÿฐ์ฒ˜๊ฐ€ ์‹คํ–‰์ด ๋˜๋Š”๋ฐ ์šฐ์ธก ์ƒ๋‹จ์— ์ฌ๋„๋งˆํ•˜๊ฒŒ "๋ฏธ์•ˆํ•ฉ๋‹ˆ๋‹ค. ๋‹˜ ๋‚˜๋ผ์—์„œ๋Š” ๋ชปํ•ด์š”." ๋ผ๊ณ  ์จ์žˆ๊ณ  ์ž…๊ตฌ์ปท์„ ๋‹นํ–ˆ์Šต๋‹ˆ๋‹ค.

RE: https://bsky.app/profile/did:plc:de27rm6eyuf5ez6gmvjdmilq/post/3mevtwme7uc2y

1

Jaeyeol Lee shared the below article:

์™œ gaji์ธ๊ฐ€? - TS๋กœ ์•ˆ์ „ํ•˜๊ฒŒ GitHub Actions ์ž‘์„ฑํ•˜๊ธฐ

๊ฐœ๋ฐœ๊ณฐ @gaebalgom@hackers.pub

์ตœ๊ทผ์— ์ €๋Š” TS๋กœ GitHub Actions๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•œ ํˆด์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์ด๋ฆ„ํ•˜์—ฌ GitHub Actions Justified Improvements, gaji ๋ผ๋Š” ํˆด์ž…๋‹ˆ๋‹ค. ์ €๋Š” ์™œ TS๋กœ GitHub Actions๋ฅผ ์ž‘์„ฑํ•˜๊ฒŒ ๋˜์—ˆ์œผ๋ฉฐ, ๊ธฐ์กด ํˆด๋“ค๊ณผ ์–ด๋–ค ์ ์ด ๋‹ค๋ฅผ๊นŒ์š”? ๊ฐ™์ด ์•Œ์•„๋ณด์‹œ์ฃ .

๊ฐ€์ง€ ๊ณต์‹ ๋ฌธ์„œ

Toss Client DevOps Team์—์„œ์˜ ์ธํ„ด ๊ทผ๋ฌด

์˜ฌํ•ด 1์›”๋ถ€ํ„ฐ, ์ €๋Š” Toss Client DevOps Team ์—์„œ ์ธํ„ด ๊ทผ๋ฌด๋ฅผ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. Client DevOps Team์„ ๊ฐ€์žฅ ๋‹จ์ˆœํ•˜๊ฒŒ ํ‘œํ˜„ํ•˜์ž๋ฉด, ํด๋ผ์ด์–ธํŠธ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋น ๋ฅด๊ณ  ์•ˆ์ „ํ•˜๊ฒŒ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ๋Š” ์ธํ”„๋ผ ํ™˜๊ฒฝ์„ ๊ตฌ์ถ•ํ•˜๋Š” ํŒ€์ž…๋‹ˆ๋‹ค. ์ œ๊ฐ€ ์ฃผ๋กœ ์ง„ํ–‰ํ•œ ์ž‘์—…์€ ๊ธฐ์กด ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ GitHub Actions๋กœ ์ „ํ™˜ํ•˜๊ณ , ์ƒˆ๋กœ์šด ๊ฒ€์‚ฌ๋ฅผ ์œ„ํ•œ ์ปค์Šคํ…€ ์•ก์…˜์„ ๋งŒ๋“œ๋Š” ์ผ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์ˆ˜์‹ญ ๊ฐœ์˜ ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ๋‹ค๋ฃจ๋ฉด์„œ, ๋น ๋ฅด๊ณ  ์•ˆ์ „ํ•œ ๋ฐฐํฌ ์ธํ”„๋ผ๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋Š” ํŒ€์—์„œ ์ •์ž‘ ๊ทธ ์ธํ”„๋ผ๋ฅผ ๋งŒ๋“œ๋Š” ๊ณผ์ • ์ž์ฒด๋Š” ๋А๋ฆฌ๊ณ  ๋ถˆ์•ˆ์ „ํ•˜๋‹ค๋Š” ๊ฑธ ์ฒด๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์˜คํƒ€ ํ•˜๋‚˜๋ฅผ ํ™•์ธํ•˜๋ ค๋ฉด ์ปค๋ฐ‹ โ†’ ํ‘ธ์‹œ โ†’ CI ์‹คํ–‰ โ†’ ์‹คํŒจ ํ™•์ธ์ด๋ผ๋Š” ์‚ฌ์ดํด์„ ๋ฐ˜๋ณตํ•ด์•ผ ํ–ˆ๊ณ , ๋กœ์ปฌ์—์„œ ์žฌํ˜„ํ•  ๋ฐฉ๋ฒ•์ด ์—†์œผ๋‹ˆ git ์‹ค๋ ฅ๋งŒ ๋Š˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ธํ„ด์„ ํ•˜๋ฉฐ ์ž๋ฆฌ์žก์€ ์ƒ๊ฐ๋“ค

์ด๋Ÿฐ ์ธํ„ด ๊ทผ๋ฌด๋ฅผ ํ•˜๋ฉด์„œ, ๋ช‡๊ฐ€์ง€ ์ƒ๊ฐ์ด ์ž๋ฆฌ์žก์•˜์Šต๋‹ˆ๋‹ค. ์ฒ ํ•™๊นŒ์ง€๋Š” ์•„๋‹ˆ๊ณ , ๋‹จ์ˆœํ•œ ์ƒ๊ฐ ์ •๋„์ž…๋‹ˆ๋‹ค.

  1. ์ž…์ถœ๋ ฅ์ด ๋ช…ํ™•ํ•ด์•ผ ์ข‹์€ ์†Œํ”„ํŠธ์›จ์–ด์ž…๋‹ˆ๋‹ค.

  2. YAML์€ ๋™์ž‘์„ ํ‘œํ˜„ํ•  ์–ธ์–ด๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. Actions๋Š” ์ž…์ถœ๋ ฅ๊ณผ ์‚ฌ์ด๋“œ์ดํŽ™ํŠธ๊ฐ€ ์žˆ๋Š” ๋™์ž‘์ž…๋‹ˆ๋‹ค. ์ด๊ฑธ ๋ฐ์ดํ„ฐ๋ฅผ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ์–ธ์–ด์ธ YAML๋กœ ํ‘œํ˜„ํ•˜๋Š” ๊ฒƒ ์ž์ฒด๊ฐ€ ์–ธ์–ด์˜ ์‚ฌ์šฉ์ฒ˜๊ฐ€ ์ž˜๋ชป๋œ ๊ฒƒ์ด ์•„๋‹๊นŒ์š”? ์„ ์–ธ์ ์ด์ง€ ์•Š์€ ๊ฑธ ์„ ์–ธ์ ์œผ๋กœ ํ‘œํ˜„ํ•˜๋ ค๋‹ค ๋ณด๋‹ˆ, YAML ์•ˆ์— ์…ธ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋„ฃ๋Š” ๊ธฐํ˜•์ ์ธ ๊ตฌ์กฐ๊ฐ€ ๋˜์–ด๋ฒ„๋ ธ์Šต๋‹ˆ๋‹ค.

  3. ์–ด๋А ํ™˜๊ฒฝ์—์„œ๋“  ์žฌํ˜„ ๊ฐ€๋Šฅํ•ด์•ผ ์ข‹์€ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

gaji๋Š” ์ด ์ค‘ 1, 2๋ฒˆ์—์„œ ์ถœ๋ฐœํ–ˆ๊ณ , 3๋ฒˆ์€ act ๊ฐ™์€ ๋„๊ตฌ์˜ ์˜์—ญ์ž…๋‹ˆ๋‹ค.

GitHub Actions์˜ 3๊ฐ€์ง€ ๊ตฌ์กฐ์  ๋ฌธ์ œ

์œ„ ์ƒ๊ฐ์„ ๊ฐ€์ง€๊ณ  GitHub Actions๋ฅผ ๋ณด๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  1. YAML์€ ๋ฐ์ดํ„ฐ ํ‘œํ˜„ ์–ธ์–ด์ง€, ๋™์ž‘์„ ํ‘œํ˜„ํ•˜๊ธฐ์— ์ ํ•ฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  2. ํƒ€์ž… ๊ฒ€์‚ฌ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์™ธ๋ถ€ ์ €์žฅ์†Œ์— ์˜์กดํ•  ์ผ์ด ๋งŽ์€๋ฐ(actions/checkout@v5์กฐ์ฐจ ์™ธ๋ถ€ ์ €์žฅ์†Œ์ž…๋‹ˆ๋‹ค), ์ด๋“ค์ด ์š”๊ตฌํ•˜๋Š” ์ž…๋ ฅ์— ๋Œ€ํ•œ ๊ฒ€์ฆ์ด ์ „ํ˜€ ์—†์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ๋ฌธ์„œ๋ฅผ ๋ณด๊ณ  ์ผ์ผ์ด ํ˜•์‹์— ๋งž๊ฒŒ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  3. ๋กœ์ปฌ์—์„œ ์žฌํ˜„ํ•˜๊ธฐ๊ฐ€ ํž˜๋“ญ๋‹ˆ๋‹ค.

์ด ์„ธ ๊ฐ€์ง€๊ฐ€ ๊ฒฐํ•ฉํ•ด GitHub Actions๋Š” ์‹คํ–‰ํ•˜๊ธฐ ์ „๊นŒ์ง€ ๊ฐ„๋‹จํ•œ ์˜คํƒ€ ํ•˜๋‚˜๋„ ๋ชป ์ฐพ๋Š” ํ”Œ๋žซํผ์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

name: CI
on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5

      - uses: actions/setup-node@v4
        with:
          node-versoin: '20'  # ํ‚ค ์ด๋ฆ„ ์˜คํƒ€! ๋Ÿฐํƒ€์ž„๊นŒ์ง€ ์˜ค๋ฅ˜ ์—†์Œ โŒ
          cache: 'npm'

      - run: npm ci
      - run: npm test

gaji๋Š” ์ฒซ ๋ฒˆ์งธ์™€ ๋‘ ๋ฒˆ์งธ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ ์ง‘์ค‘ํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ์กด ๋„๊ตฌ๋“ค๊ณผ์˜ ๋น„๊ต

actionlint

์†”์งํžˆ ๋งํ•˜๋ฉด, gaji๋ฅผ ๋งŒ๋“ค ๋‹น์‹œ์—๋Š” actionlint์˜ ์กด์žฌ๋ฅผ ๋ชฐ๋ž์Šต๋‹ˆ๋‹ค. ์ดํ›„์— ์•Œ๊ฒŒ ๋˜์—ˆ๋Š”๋ฐ, ํ›Œ๋ฅญํ•œ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ${{ }} ํ‘œํ˜„์‹์˜ ํƒ€์ž… ์ฒดํฌ, ์•ก์…˜ ์ž…๋ ฅ ๊ฒ€์ฆ, shellcheck ํ†ตํ•ฉ ๋“ฑ YAML ์›Œํฌํ”Œ๋กœ์šฐ์˜ ์˜ค๋ฅ˜๋ฅผ ์ƒ๋‹นํžˆ ์ž˜ ์žก์•„์ค๋‹ˆ๋‹ค.

๋‹ค๋งŒ ๊ทผ๋ณธ์ ์ธ ์ ‘๊ทผ ๋ฐฉ์‹์ด ๋‹ค๋ฆ…๋‹ˆ๋‹ค. actionlint๋Š” YAML์„ ์œ ์ง€ํ•˜๋ฉด์„œ ์‚ฌํ›„์— ์˜ค๋ฅ˜๋ฅผ ์žก๋Š” ๋ฆฐํ„ฐ์ด๊ณ , gaji๋Š” YAML ์ž์ฒด๋ฅผ ๋ฒ—์–ด๋‚˜์„œ ์ž‘์„ฑ ์‹œ์ ์— ์˜ค๋ฅ˜๋ฅผ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ์ ‘๊ทผ์ž…๋‹ˆ๋‹ค. ๋ฆฐํ„ฐ๋Š” "์‹ค์ˆ˜๋ฅผ ์•Œ๋ ค์ฃผ๊ณ ", ํƒ€์ž… ์‹œ์Šคํ…œ์€ "์‹ค์ˆ˜๋ฅผ ํ•˜๊ธฐ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค." ๊ฐœ๋ฐœ ๊ฒฝํ—˜ ์ธก๋ฉด์—์„œ๋„, actionlint๋Š” ๋ณ„๋„ CLI๋ฅผ ์‹คํ–‰ํ•˜๊ฑฐ๋‚˜ ์—๋””ํ„ฐ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ•ด์•ผ ํ•˜์ง€๋งŒ, gaji๋Š” TypeScript ๋„ค์ดํ‹ฐ๋ธŒ ์ž๋™์™„์„ฑ๊ณผ ์ธ๋ผ์ธ ํƒ€์ž… ํžŒํŠธ๊ฐ€ ์—๋””ํ„ฐ์—์„œ ์ฆ‰์‹œ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

์ด ๋‘˜์„ ๊ฐ™์ด ์“ฐ๋ฉด ๋”์šฑ ์ข‹์Šต๋‹ˆ๋‹ค. gaji๊ฐ€ ์ƒ์„ฑํ•œ YAML์„ actionlint๋กœ ๊ฒ€์ฆํ•˜๋ฉด ๊ฐ€์žฅ ์ด์ƒ์ ์ธ ์กฐํ•ฉ์ด ๋ฉ๋‹ˆ๋‹ค. gaji๊ฐ€ TypeScript ๋‹จ์—์„œ ์•ก์…˜ ์ž…๋ ฅ์˜ ํƒ€์ž…์„ ์žก๊ณ , actionlint๊ฐ€ ${{ }} ํ‘œํ˜„์‹ ๊ฒ€์ฆ ๊ฐ™์€ YAML ๋‹จ์˜ ๊ฒ€์‚ฌ๋ฅผ ๋ณด์™„ํ•ฉ๋‹ˆ๋‹ค.

emmanuelnk/github-actions-workflow-ts

github-actions-workflow-ts๋Š” TS๋กœ GitHub Actions๋ฅผ ํ‘œ๊ธฐํ•œ๋‹ค๋Š” ์•„์ด๋””์–ด์˜ ์ถœ๋ฐœ์ ์ด ๋œ ํ”„๋กœ์ ํŠธ์ž…๋‹ˆ๋‹ค. action.yml์—์„œ ํƒ€์ž…์„ ์ž๋™ ์ƒ์„ฑํ•œ๋‹ค๋Š” ์•„์ด๋””์–ด ์ž์ฒด๋Š” gaji์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋งŒ ์ฝ”๋“œ์  ์˜ ์ฃผ์ฒด๊ฐ€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. github-actions-workflow-ts๋Š” ๋ฉ”์ธํ…Œ์ด๋„ˆ๊ฐ€ trackedActions ๋ชฉ๋ก์„ ๊ด€๋ฆฌํ•˜์—ฌ npm ํŒจํ‚ค์ง€๋กœ ๋ฐฐํฌํ•˜๋Š” ๋ฐฉ์‹์ด๊ณ , gaji๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ๋ชจ๋“  ์•ก์…˜์— ๋Œ€ํ•ด ์ฆ‰์‹œ ๋กœ์ปฌ์—์„œ ํƒ€์ž…์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

github-actions-workflow-ts์˜ ์žฅ์ ์€ ๋ช…ํ™•ํ•ฉ๋‹ˆ๋‹ค. npm ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•˜๋ฉด ๋ฐ”๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ณ , ์‚ฌ์šฉ์ž๊ฐ€ ๋ณ„๋„์˜ ์ฝ”๋“œ์  ์„ ์‹คํ–‰ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. step outputs์— ๋Œ€ํ•œ ํƒ€์ž… ์•ˆ์ „์„ฑ๋„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

๋ฐ˜๋ฉด ๋‹จ์ ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฉ”์ธํ…Œ์ด๋„ˆ๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” ๋ชฉ๋ก์— ์žˆ๋Š” ์•ก์…˜๋งŒ ํƒ€์ž…์ด ์ง€์›๋˜๋ฏ€๋กœ, ์ปค์Šคํ…€ ์•ก์…˜์ด๋‚˜ GHE ๋‚ด๋ถ€ ์•ก์…˜์€ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ƒˆ ์•ก์…˜์ด๋‚˜ ๋ฒ„์ „ ์ถ”๊ฐ€๋„ ๋ฉ”์ธํ…Œ์ด๋„ˆ์— ์˜์กดํ•˜๊ณ , ์™ธ๋ถ€ JS ๋Ÿฐํƒ€์ž„์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

gaji์˜ ์žฅ์ ์€ ์‚ฌ์šฉ์ž๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ์–ด๋–ค ์•ก์…˜์ด๋“  ์ฆ‰์‹œ ํƒ€์ž…์„ ์ƒ์„ฑํ•œ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. ์ปค์Šคํ…€ ์•ก์…˜์ด๋“  GHE ๋‚ด๋ถ€ ์•ก์…˜์ด๋“  ์ƒ๊ด€์—†์Šต๋‹ˆ๋‹ค. Rust ๋ฐ”์ด๋„ˆ๋ฆฌ๋กœ ๋™์ž‘ํ•˜๋ฏ€๋กœ JS ๋Ÿฐํƒ€์ž„๋„ ๋ถˆํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด ๋‹จ์ ์œผ๋กœ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ gaji dev๋ฅผ ์‹คํ–‰ํ•ด์•ผ ํƒ€์ž…์ด ์ƒ์„ฑ๋˜๊ณ , ํƒ€์ž…์ด ๋กœ์ปฌ์—์„œ ์ƒ์„ฑ๋˜๋ฏ€๋กœ ํ”„๋กœ์ ํŠธ๋งˆ๋‹ค ์„ธํŒ…์ด ํ•„์š”ํ•˜๋‹ค๋Š” ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ €๋Š” GHE ํ™˜๊ฒฝ์—์„œ ์ˆ˜๋งŽ์€ ์ปค์Šคํ…€ ์•ก์…˜์„ ๋‹ค๋ค˜๋˜ ๊ฒฝํ—˜ ๋•Œ๋ฌธ์—, gaji ์ชฝ์˜ ์ ‘๊ทผ์ด ํ•„์š”ํ•˜๋‹ค๊ณ  ํŒ๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค.

gaji์˜ ์ ‘๊ทผ๋ฒ•

์™œ ์ด๋ ‡๊ฒŒ ๋งŒ๋“ค์—ˆ๋Š”๊ฐ€

์™œ Rust์ธ๊ฐ€? ๋น ๋ฅด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋‹จ์ˆœํžˆ ๋นŒ๋“œ๋œ ๋ฐ”์ด๋„ˆ๋ฆฌ์˜ ์†๋„๋ฅผ ์ด์•ผ๊ธฐํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. clippy, rustfmt ๋“ฑ ์—ฌ๋Ÿฌ ๊ฒ€์‚ฌ ๋„๊ตฌ๊ฐ€ ๋‚ด์žฅ๋˜์–ด ์žˆ์–ด์„œ LLM์„ ์ด์šฉํ•œ ๊ฐœ๋ฐœ ์†๋„๋ฅผ ํฌ๊ฒŒ ์ค„์—ฌ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ๋•๋ถ„์— ์ธํ„ด์„ ํ•˜๋ฉด์„œ๋„ ๋น ๋ฅด๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ oxc ๋“ฑ Rust๋กœ ์ž‘์„ฑ๋œ TypeScript ์ง€์› ๋„๊ตฌ๋“ค์ด ์ด๋ฏธ ์„ฑ์ˆ™ํ•ด ์žˆ์–ด์„œ, Rust์—์„œ TypeScript๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ฒƒ ๋˜ํ•œ ํŽธํ–ˆ์Šต๋‹ˆ๋‹ค.

์™œ TypeScript์ธ๊ฐ€? ์šฐ์„  ์ œ๊ฐ€ JS/TS ๊ฐœ๋ฐœ์ž์ž…๋‹ˆ๋‹ค. TypeScript์˜ ํƒ€์ž… ์‹œ์Šคํ…œ์€ ๊ฐ•๋ ฅํ•˜๋ฉด์„œ๋„ ๋ณดํŽธ์ ์ด๋ผ ๋งŽ์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ด๋ฏธ ์ต์ˆ™ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  GitHub Actions์˜ YAML ๊ตฌ์กฐ๊ฐ€ ๋ณธ์งˆ์ ์œผ๋กœ JSON๊ณผ ์œ ์‚ฌํ•˜๋ฏ€๋กœ, TS/JS์—์„œ JSON-like ๊ฐ์ฒด๋กœ ํ‘œํ˜„ํ•˜๊ธฐ๊ฐ€ ๋งค์šฐ ์ž์—ฐ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ๋‹จ์ ์œผ๋กœ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ์€ ๋ชจ๋“  gaji ์›Œํฌํ”Œ๋กœ์šฐ ํŒŒ์ผ์ด ๊ทธ ์ž์ฒด๋กœ ์œ ํšจํ•œ TS ํŒŒ์ผ์ด๋ผ๋Š” ์ ์ž…๋‹ˆ๋‹ค. Deno์ฒ˜๋Ÿผ TS๋ฅผ ๋ฐ”๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ํ™˜๊ฒฝ์—์„œ gaji๋กœ ์ž‘์„ฑ๋œ ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด, ํ•ด๋‹น ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ JSON์œผ๋กœ ํ‘œํ˜„ํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

์™œ action.yml ์ž๋™ ์ฝ”๋“œ์  ์ธ๊ฐ€? Client DevOps Team์—์„œ ์ปค์Šคํ…€ ์•ก์…˜์„ ์ž‘์„ฑํ•˜๋Š” ์ผ์„ ํ–ˆ๊ณ , ์ด๋ฏธ ์ƒ๋‹นํžˆ ๋งŽ์€ ์ปค์Šคํ…€ ์•ก์…˜์ด ์กด์žฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋“ค์˜ ๋ฌธ์„œ๋ฅผ ์ผ์ผ์ด ๋ณด๋ฉฐ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ํž˜๋“ค์—ˆ๋˜ ๊ฒฝํ—˜์ด ์ง์ ‘์ ์ธ ๋™๊ธฐ์˜€์Šต๋‹ˆ๋‹ค. Hackers.pub์— ๊ธฐ์—ฌํ•˜๋ฉด์„œ GraphQL ์ž๋™ ์ฝ”๋“œ์  ์˜ ๊ฐœ๋…์„ ์ ‘ํ–ˆ๊ณ , ๊ฐ™์€ ์ ‘๊ทผ์„ GitHub Actions์— ์ ์šฉํ•  ์ˆ˜ ์žˆ๊ฒ ๋‹ค๊ณ  ํŒ๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ๊ตฌ์กฐ

gaji ์›Œํฌํ”Œ๋กœ์šฐ๋Š” getAction() โ†’ Job โ†’ Workflow โ†’ .build()์˜ ํ๋ฆ„์œผ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. gaji dev --watch๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์ƒˆ ์•ก์…˜ ์ฐธ์กฐ๋ฅผ ๊ฐ์ง€ํ•˜์—ฌ ์ž๋™์œผ๋กœ ํƒ€์ž…์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

import { getAction, Job, Workflow } from "../generated/index.js";

const checkout = getAction("actions/checkout@v5");
const setupNode = getAction("actions/setup-node@v4");

const build = new Job("ubuntu-latest")
  .addStep(checkout({}))
  .addStep(setupNode({
    with: {
      "node-version": "20",
      cache: "npm",
    },
  }))
  .addStep({ run: "npm ci" })
  .addStep({ run: "npm test" });

const workflow = new Workflow({
  name: "CI",
  on: { push: { branches: ["main"] } },
}).addJob("build", build);

workflow.build("ci");

์ด๋ ‡๊ฒŒ ์ž‘์„ฑํ•˜๋ฉด ๋ชจ๋“  ์•ก์…˜ ์ž…๋ ฅ์— ๋Œ€ํ•œ ์ž๋™์™„์„ฑ, ์ปดํŒŒ์ผ ์‹œ์  ํƒ€์ž… ์ฒดํฌ, action.yml ๋ฌธ์„œ์˜ IDE ํžŒํŠธ ํ‘œ์‹œ, ๊ธฐ๋ณธ๊ฐ’ ํ‘œ์‹œ๊ฐ€ ๋ชจ๋‘ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. CompositeJob์œผ๋กœ ๊ณตํ†ต ๋กœ์ง์„ ํด๋ž˜์Šค๋กœ ์ถ”์ถœํ•˜๊ฑฐ๋‚˜, CallJob์œผ๋กœ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ๋„ TS ์ฝ”๋“œ์ƒ์—์„  ์ž์—ฐ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค.

์‹ค์ œ ์‚ฌ๋ก€: gaji ์ž์ฒด์˜ ๋ฆด๋ฆฌ์ฆˆ CD

gaji๋Š” ๋ชจ๋“  ci/cd๋ฅผ gaji๋กœ ์ž‘์„ฑํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ์ค‘์—์„œ ์ œ์ผ ๋ณต์žกํ•œ release.ts๋Š” 4๊ฐœ์˜ Job์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • build: 5๊ฐœ ํ”Œ๋žซํผ(linux-x64, linux-arm64, darwin-x64, darwin-arm64, win32-x64) ํฌ๋กœ์Šค ๋นŒ๋“œ
  • upload-release-assets: GitHub Release์— ๋ฐ”์ด๋„ˆ๋ฆฌ์™€ ์ฒดํฌ์„ฌ ์—…๋กœ๋“œ
  • publish-npm: npm์— ํ”Œ๋žซํผ๋ณ„ ํŒจํ‚ค์ง€ ํผ๋ธ”๋ฆฌ์‹œ
  • publish-crates: crates.io์— OIDC ๊ธฐ๋ฐ˜ ํผ๋ธ”๋ฆฌ์‹œ

์ด ์›Œํฌํ”Œ๋กœ์šฐ๊ฐ€ YAML๋กœ ์ปดํŒŒ์ผ๋˜๋ฉด ์•ฝ 180์ค„์˜ ํ‰ํƒ„ํ•œ ๊ตฌ์กฐ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์ฃผ์„ ์—†์ด๋Š” Job ๊ฐ„ ๊ฒฝ๊ณ„๋‚˜ ์˜์กด๊ด€๊ณ„๋ฅผ ํŒŒ์•…ํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. TypeScript ๋ฒ„์ „์—์„œ๋Š” build, uploadReleaseAssets, publishNpm, publishCrates๋ผ๋Š” ๋ณ€์ˆ˜๋ช…๋งŒ์œผ๋กœ ๊ตฌ์กฐ๊ฐ€ ์ฆ‰์‹œ ํŒŒ์•…๋ฉ๋‹ˆ๋‹ค. 6๊ฐœ์˜ ์™ธ๋ถ€ ์•ก์…˜์„ ํƒ€์ž… ์•ˆ์ „ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๊ณ , ๋ณต์žกํ•œ ๋งคํŠธ๋ฆญ์Šค ๋นŒ๋“œ์™€ OS๋ณ„ ๋ถ„๊ธฐ๊ฐ€ ์ฝ”๋“œ ๊ตฌ์กฐ ์•ˆ์—์„œ ๊ฐ€๋…์„ฑ ์žˆ๊ฒŒ ํ‘œํ˜„๋ฉ๋‹ˆ๋‹ค.

gaji์˜ ํ•œ๊ณ„

gaji์—๋Š” ์—ฌ์ „ํžˆ ํ•œ๊ณ„๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

๊ทผ๋ณธ์ ์œผ๋กœ, ์ตœ์ข… ์‚ฐ์ถœ๋ฌผ์ด ์—ฌ์ „ํžˆ YAML์ž…๋‹ˆ๋‹ค. GitHub Actions ํ”Œ๋žซํผ์˜ ์ž…๋ ฅ ํ˜•์‹์ด YAML์ธ ์ด์ƒ, gaji๋„ ๊ทธ ์ œ์•ฝ ์•ˆ์— ๊ฐ‡ํž™๋‹ˆ๋‹ค. gaji๋Š” ์ด ํ”Œ๋žซํผ ์œ„์—์„œ์˜ ์ตœ์„ ์ด์ง€, ์ด์ƒ์ ์ธ ํ•ด๋‹ต์€ ์•„๋‹™๋‹ˆ๋‹ค. ์›๋ณธ action.yml์˜ inputs๊ฐ€ ๋ฌธ์ž์—ด์ด๋‚˜ ์ˆซ์ž ์ •๋„๋กœ๋งŒ ํ‘œํ˜„๋˜๊ธฐ ๋•Œ๋ฌธ์—, "npm" | "yarn" | "pnpm" ๊ฐ™์€ ์„ธ๋ฐ€ํ•œ ๊ฐ’ ์ˆ˜์ค€์˜ ํƒ€์ž…๊นŒ์ง€๋Š” ์ œ๊ณตํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ${{ matrix.target.rust_target }} ๊ฐ™์€ GitHub Actions ํ‘œํ˜„์‹๋„ ์—ฌ์ „ํžˆ ์ˆœ์ˆ˜ ๋ฌธ์ž์—ด์ด๋ผ ํƒ€์ž… ๊ฒ€์ฆ์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ์ˆ ์ ์ธ ์ œํ•œ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. gaji dev๋Š” getAction()์„ ์ •์  ๋ถ„์„ํ•ด์„œ ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด๋งŒ ์ง€์›ํ•˜๊ณ , ๋ณ€์ˆ˜๋‚˜ ํ…œํ”Œ๋ฆฟ ๋ฆฌํ„ฐ๋Ÿด์€ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋ฌธ์ž์—ด ๊ฐ’ ์ž์ฒด์˜ ์˜คํƒ€(cache: "npn" vs cache: "npm")๋„ ์žก์„ ์ˆ˜ ์—†๊ณ ์š”.

์•ž์œผ๋กœ์˜ ๋ฐฉํ–ฅ

gaji์˜ ํ˜„์žฌ ์•„ํ‚คํ…์ฒ˜๋Š” TypeScript โ†’ Parse (oxc) โ†’ Execute (QuickJS) โ†’ YAML์ž…๋‹ˆ๋‹ค. ์ฝ”๋“œ์  ์„ ๋งŒ๋“ค๋ฉด์„œ ํ•œ ๊ฐ€์ง€ ์•„์ด๋””์–ด๋ฅผ ์–ป์—ˆ๋Š”๋ฐ, ํ”„๋ก ํŠธ์—”๋“œ(์‚ฌ์šฉ์ž๊ฐ€ ์ž‘์„ฑํ•˜๋Š” ์–ธ์–ด)์™€ ๋ฐฑ์—”๋“œ(YAML ์ƒ์„ฑ)๋ฅผ ์ž˜ ๋ถ„๋ฆฌํ•˜๊ณ , ์ค‘๊ฐ„ ์–ธ์–ด๋ฅผ ์ž˜ ์ •์˜ํ•˜๋ฉด TypeScript ์™ธ์˜ ๋‹ค๋ฅธ ์–ธ์–ด๋กœ๋„ ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ฒ ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

1.0์—์„œ๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ ์‹œ์Šคํ…œ์„ ๋„์ž…ํ•ด ๋‹ค๋ฅธ ์–ธ์–ด ์ง€์›์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋Š” ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ค ๊ณ„ํš์ž…๋‹ˆ๋‹ค. gaji์˜ ํ•ต์‹ฌ ๊ฐ€์น˜์ธ action.yml ์ž๋™ ํƒ€์ž… ์ƒ์„ฑ์„ TypeScript์— ๊ตญํ•œํ•˜์ง€ ์•Š๊ณ  ํ™•์žฅํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

Special Thanks

gaji ๋ธŒ๋žœ๋“œ

์ด๋ฆ„ ์ œ์•ˆ์„ ํ•ด ์ฃผ์‹  kiwiyou ๋‹˜, RanolP ๋‹˜, ๋กœ๊ณ  ์ œ์ž‘์„ ํ•ด ์ฃผ์‹  sij411 ๋‹˜๊ป˜ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. Client DevOps Team์—๊ฒŒ๋„ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ด ํŒ€์—์„œ ๊ฒช์€ ๊ฒฝํ—˜์ด ์•„๋‹ˆ์—ˆ์œผ๋ฉด YAML๊ณผ GitHub Actions์— ๋Œ€ํ•ด ์ƒ๊ฐํ•ด ๋ณด์ง€ ์•Š์•˜์„ ๊ฒ๋‹ˆ๋‹ค. emmanuelnk/github-actions-workflow-ts์—๊ฒŒ๋„ ๊ฐ์‚ฌ๋ฅผ ํ‘œํ•ฉ๋‹ˆ๋‹ค. TS๋กœ GitHub Actions๋ฅผ ํ‘œ๊ธฐํ•œ๋‹ค๋Š” ์•„์ด๋””์–ด์™€ ๊ธฐ๋ณธ์ ์ธ TS API ์„ค๊ณ„๋Š” ์—ฌ๊ธฐ์„œ ๊ฐ€์ ธ์™”์Šต๋‹ˆ๋‹ค.

Read more โ†’
4
0

So I just want to make sure I get this right: a substantial part of the US population *still* is ok with gutting health and safety measures via the FDA, CDC, and EPA, and has no problem paying extra for stuff that's made overseas, don't see why it's a good idea to do basic science and research, doesn't mind having a cabal of wealthy lawless oligarchs running their lives, and is fine with the government brutalizing people because they don't have the right papers. That's where we're at?

0
0
0
0
0
1
1
1
0

๋ฆฌ๋ˆ…์Šค๋ฅผ ์“ธ์ˆ˜๋ก ์œˆ๋„์šฐ๊ฐ€ ํญ๋ฃก์  OS๋ผ๋Š”๊ฒƒ์„ ๋А๋ผ๊ณ  ์žˆ๋‹ค. ์„ธ์ƒ์— ์„ค์ •์—์„œ PROTON๋ฒ„์ „ ์กฐ๊ธˆ ๋ณ€๊ฒฝํ•ด์คฌ๋‹ค๊ณ  ์‹คํ–‰ ์ž์ฒด๊ฐ€ ์™„์ „์ด ์™€๋ฅด๋ฅด ๋ฌด๋„ˆ์ง€๋Š”๊ฑด ๋˜ ๋ญ๋ƒ? ๋•๋ถ„์— ๋„ฅ์Šจ ํ”Œ๋Ÿฌ๊ทธ๋ž‘ ๋งˆ๋น„๋…ธ๊ธฐ ๋ชจ๋ฐ”์ผ(์‚ฌ์ด๋ฒ„ ๋ถ„์žฌ) ์žฌ์„ค์น˜ ์ค‘.

0
0