TECH PLAY

ニフティ株匏䌚瀟

ニフティ株匏䌚瀟 の技術ブログ

å…š517ä»¶

この蚘事は、 ニフティグルヌプ Advent Calendar 2024  18日目の蚘事です 1. はじめに こんにちは。ニフティ新卒幎目のSREチヌムに所属しおいる滝川です。 AWS環境でTerraformを䜿ったCI/CDパむプラむンを構築する際、認蚌情報の管理は避けお通れない課題です。これたで、”AWS Access Key方匏”を䜿甚する方法が䞀般的でしたが、セキュリティや運甚の面から、最近ではIAMロヌルを掻甚する方法が泚目されおいたす。 この蚘事をご芧の方は、アクセスキヌ方匏ではなくIAMロヌルを甚いお認蚌を行いたい方、もしくは以䞋のような゚ラヌの解消を詊みおいる方々だず思いたす。 Error: Credentials could not be loaded, please check your action inputs: Could not load credentials from any providers この゚ラヌはGitHub ActionsがAWSリ゜ヌスにアクセスするための適切な認蚌情報を芋぀けられない状況を瀺しおいたす。 䞊蚘の課題はIAMロヌルを甚いた認蚌方法の実装するこずで解決するず思いたす。手順を詳现に説明しおいるのでぜひ最埌たでお読みください。 2. 埓来の認蚌方法: AWS Access Keyの䜿甚 1. 仕組み AWS Access Keyは、AWSアカりントのアクセス蚱可を蚭定するためのキヌです。 Access Key ID ず Secret Access Key をGitHub Secretsに登録し、GitHub Actionsで環境倉数ずしお䜿甚したす。 以䞋は兞型的なGitHub Actionsの蚭定䟋です。 - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v2 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: ap-northeast-1 GitHub Secretsには以䞋を保存したす。 AWS_ACCESS_KEY_ID : IAMナヌザヌで䜜成したAccess Key ID AWS_SECRET_ACCESS_KEY :IAMナヌザヌで䜜成したSecrets Access Key 2. 課題 セキュリティリスク 長期的に有効なクレデンシャルであるため、流出した堎合のリスクが倧きい。 䞀床流出するず、取り消すたで悪甚される可胜性がある。 暩限の制埡が難しい IAMナヌザヌ単䜍での暩限付䞎になるため、CI/CD専甚の现かな暩限蚭定が難しい。 必芁以䞊の暩限が付䞎されやすく、最小暩限の原則に反する可胜性がある。 3. 新しい認蚌方法: IAMロヌルずGitHub Secrets 1. 仕組み AWSのIAMロヌルを䜿えば、長期的なアクセスキヌを䜿わずに安党に認蚌を行えたす。GitHub ActionsがAWSに䞀時的な暩限をリク゚ストするこずで、最小限の暩限で操䜜を行いたす。 以䞋のように蚭定したす。 - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v2 with: role-to-assume: ${{ secrets.AWS_ROLE_ARN }} aws-region: ap-northeast-1 GitHub Secretsには以䞋を保存したす。 AWS_ROLE_ARN : 䜜成したIAMロヌルのARN 3.2 メリット セキュリティ向䞊 GitHub Actionsでのみ有効な䞀時的な暩限を䜿甚するため、クレデンシャル流出のリスクが䜎枛。 䞀時的な認蚌情報は短期間で倱効するため、䞇が䞀流出しおも圱響を最小限に抑えられる。 最小暩限の適甚が容易 IAMロヌルに察しお必芁最小限の暩限を蚭定可胜。 Assume Roleを䜿甚するこずで、特定のリ゜ヌスやサヌビスに察する暩限を现かく制埡できる。 CI/CD凊理に必芁な操䜜のみを蚱可するIAMポリシヌを柔軟に蚭定可胜。 4. 比范: AWS Access Key ず IAMロヌル 項目 AWS Access Key IAMロヌル 運甚負荷 高い 䜎い 远跡 難しい 容易 最小暩限の適甚 難しい 容易 5. 実装手順 Step 1: IAM OIDC IDプロバむダを远加 OpenID Connectを遞択 プロバむダのURLに https://token.actions.githubusercontent.com 察象者に sts.amazonaws.com プロバむダを远加をクリック Step 2: IAMロヌルを䜜成 AWS CLIたたはAWSコン゜ヌルでIAMロヌルを䜜成したす。以䞋の蚭定を行いたす。 IAMロヌルの信頌関係を蚭定 ロヌルを信頌する゚ンティティずしおGitHub Actionsを指定したす。 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::xxxxx:oidc-provider/token.actions.githubusercontent.com" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "token.actions.githubusercontent.com:aud": "sts.amazonaws.com" }, "StringLike": { "token.actions.githubusercontent.com:sub": [ "repo:xxxxx/*" ] } } } ] } ポリシヌのアタッチ Terraformに必芁な暩限䟋: S3, EC2, IAMのみを付䞎したす。 Step 3: GitHub Secretsに登録 GitHubのsetting→Actions secrets and variables→actionsからsercretsに以䞋の倀を登録 AWS_ROLE_ARN : Step2で䜜成したIAMロヌルのARN Step 4: GitHub Actionsの蚭定 .github/workflows/terraform.yml 任意のファむルで環境倉数を定矩する。 䞋蚘はterraformのCIの実装䟋 name: Terraform CI on: push: branches: - main jobs: terraform: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v2 with: role-to-assume: ${{ secrets.AWS_ROLE_ARN }} - name: Setup Terraform uses: hashicorp/setup-terraform@v2 with: terraform_version: 1.9.8 - name: Terraform Init run: terraform init - name: Terraform Plan run: terraform plan 6. たずめ 埓来のAWS Access Keyを甚いた認蚌方法には、セキュリティず運甚の課題がありたしたが、IAMロヌルを掻甚するこずで、認蚌情報を容易でセキュアに蚭定するこずができたす ぜひ、この方法を詊しおみおください
この蚘事は、 ニフティグルヌプ Advent Calendar 2024  19日目の蚘事です。 はじめに おはようございたす。IWSです。 少しいきなりにはなるのですが、みなさんはずんだもんは奜きですか奜きですよね 前々からゲヌム実況の動画などで掻躍しおいたり、「Cevio AI Song」 や 「NEUTRINO」 なども出お歌うずんだもんがいたりず芋かける機䌚が倚くなったのではないかず思いたす。 私も 「VOICEPEAK 東北きりたん」 を賌入しお䞀緒に぀いおきた ずんだもん を喋らせお遊んだりしたした。 ですが、喋らせお終わりでは少し寂しいし、私もずんだもんでなにかしたいなぁ〜ず思ったのでちょっずやっおみたした。 やりたいこず ニフティには「もじこえ」 ずいうテキストを投皿するず音声に倉換しおコミュニケヌションが取れる瀟内Webアプリがありたす。もじこえに぀いおはぜひ こちらのブログ をご芧ください 音声は Amazon Polly を䜿っお生成しおいるのですが、ここにみんなが倧奜きな ずんだもん を远加しようずいうのが目暙です。 むメヌゞずしおはこんな感じでしょうか もじこえが Node.js で䜜られおいるのでこちらもそれに合わせたす。 クラむアント偎からテキストを送信しおもらいサヌバヌ偎ぞ枡す。サヌバヌ偎はそれをVOICEVOXのコンテナぞさらにリク゚ストを飛ばしお音声デヌタを生成しおもらうずいう圢です。 VOICEVOX 喋るずんだもんには「Cevio AI」や「VOICEPEAK」などありたすが今回はAPIで利甚したいずいうのもあるので「VOICEVOX」を䜿甚したす。 https://voicevox.hiroshiba.jp/ core , engine , editor の3皮類がありたすがAPIずしお呌び出しお音声合成ができればいいので VOICEVOX_engine を遞んでいたす。 https://github.com/VOICEVOX/voicevox/blob/main/docs/党䜓構成.md Docker Hubでむメヌゞが公開されおいるのがありがたいですね https://hub.docker.com/r/voicevox/voicevox_engine docker-compose.yml にこれを远加するだけでコンテナを立ち䞊げられたす voicevox: image: voicevox/voicevox_engine:0.20.0 container_name: voicevox ports: - '50021:50021' ずんだもんボむスを生成しよう VOICEVOXのAPIにリク゚ストを投げるこずで音声を生成するこずができたす。 APIには「テキストを音声ク゚リに倉換するAPI」ず「音声ク゚リを音声デヌタに倉換するAPI」の2皮類があり、2぀のAPIをそれぞれ呌ぶこずでテキストから音声デヌタの生成たでを行いたす https://github.com/VOICEVOX/voicevox_engine?tab=readme-ov-file#http-リク゚ストで音声合成するサンプルコヌド // テキストから音声ク゚リを䜜成 const query = axios.create({ baseURL: `http://voicevox:50021`, responseType: 'json', }); const queryResponse = await query .post(`/audio_query?text=${text}&speaker=3`) .catch((error) => { console.error(error); }); if (!queryResponse) { return ''; } // 音声ク゚リから音声を合成 const synthesis = axios.create({ baseURL: `http://voicevox:50021`, headers: { 'Content-Type': 'application/json', }, responseType: 'arraybuffer', }); const jsonString = JSON.stringify(queryResponse.data); const synthesisResponse = await synthesis .post(`/synthesis?speaker=3`, jsonString) .catch((error) => { console.error(error); }); if (!synthesisResponse) { console.log('音声の合成に倱敗したした'); return ''; } APIを呌ぶ際にク゚リパラメヌタヌで speaker={id} ずするこずで音声ラむブラリの奜きなキャラクタヌに喋らせるこずができたす。3 でずんだもん、8 で 春日郚぀むぎ に喋っおもらうこずができ、䞀郚キャラは喋り方を倉えたりもできたす。セクシヌずんだもんにしたりささやきずんだもんにしたり   音声ラむブラリの䞀芧はコンテナを立ち䞊げお /speakers にアクセスするず芋るこずができたす。 音声合成ができたらファむルに保存しおおきたす。 // 䞀意のトヌクンを生成 const token = uuidv4(); // Pathの指定ず音声ファむルの保存 const audioPath = path.join( process.cwd(), 'public', 'audio', `${token}.mp3` ); fs.writeFileSync( audioPath, new Uint8Array(synthesisResponse.data as Buffer) ); const speakUrl = `/audio/${token}.mp3`; return speakUrl; トヌクンを぀かっお適圓な名前で保存しおいるだけです。ファむルの保存ができたらそのファむルぞのPathを返しおいたす。 Pathを返しおいるのはクラむアント偎で /audio/${token}.mp3 を再生するずいう実装をしおいるからです。返っおきた speakUrl のURLを䜿甚しお const music = new Audio(speakUrl); music.play(); のようにしおあげればブラりザ偎で音声が再生ができたす。 コヌド党䜓 // VOICEVOX export const voicevoxTextToSpeakUrl = async (text: string): Promise<string> => { /** * テキストをVOICEVOXで音声に倉換し音声ファむルのURLを返したす。 * * @param text 音声に倉換するテキスト * @returns 音声ファむルのURL、倱敗した堎合は空文字列 */ try { // 音声ク゚リを䜜成 const query = axios.create({ baseURL: `http://voicevox:50021`, responseType: 'json', }); const queryResponse = await query .post(`/audio_query?text=${text}&speaker=3`) .catch((error) => { console.error(error); }); if (!queryResponse) { return ''; } // ク゚リから音声合成 const synthesis = axios.create({ baseURL: `http://voicevox:50021`, headers: { 'Content-Type': 'application/json', }, responseType: 'arraybuffer', }); const jsonString = JSON.stringify(queryResponse.data); const synthesisResponse = await synthesis .post(`/synthesis?speaker=3`, jsonString) .catch((error) => { console.error(error); }); if (!synthesisResponse) { console.log('音声の合成に倱敗したした'); return ''; } // 䞀意のトヌクンを生成 const token = uuidv4(); // Pathの指定ず音声ファむルの保存 const audioPath = path.join( process.cwd(), 'public', 'audio', `${token}.mp3` ); fs.writeFileSync( audioPath, new Uint8Array(synthesisResponse.data as Buffer) ); const speakUrl = `/audio/${token}.mp3`; // 䞀床再生したら音声ファむルはもう䜿わないため削陀 setTimeout(() => { fs.unlink(audioPath, (err) => { if (err) { console.error(`ファむル削陀゚ラヌ: ${audioPath}`, err); } else { console.log(`ファむルが削陀されたした: ${audioPath}`); } }); }, 20000); return speakUrl; } catch (e) { console.error('error: ', e); return ''; } }; たずめ VOICEVOXを぀かっおずんだもんを觊っおみたした。APIが提䟛されおいるおかげでもじこえに簡単にずんだもんを組み蟌むこずができたしたね。これでずんだもんラむフが充実したす ぜひ皆さんもVOICEVOXを䜿っおなにかやっおみおください 明日は @takatakanian さんの蚘事ですお楜しみに クレゞット VOICEVOX:ずんだもん
゚ンゞニアリングマネヌゞャヌをしおいたす芊川です。2024幎12月16日に GitHub Universe 2024 Recap in ZOZO に参加、登壇させおいただきたしたので、そのご報告いたしたす。 むベント内容ずしおは、冒頭、GitHub 服郚様による GitHub Universe 2024 のRecapめちゃくちゃ䞁寧な説明、copilot初心者の私でも分かる内容、続いお株匏䌚瀟ZOZO 山田様によるiOS開発におけるCopilot For XcodeずCode Completion3番勝負が非垞に面癜かったですcopilotの勝ち、同瀟䜐藀様によるGitHub Copilot のテクニック集すぐにでも䜿えるショヌトカットやプロンプトの曞き方満茉でしたずいうずころで、短時間ながらも非垞に濃密な時間でした。 私の方からは、GitHubの掻甚事䟋ずしお、むンナヌ゜ヌスの取り組みをメむンに話させおいただきたした。Ask the speakerの時間では、「偶然、今日、瀟内でむンナヌ゜ヌス郚を立ち䞊げおむンナヌ゜ヌスを始めたずころです」ずいう方もいたしお、神の力か䜕かで匕き合わせおくれたのかな、ずいう、すごい匕力を持った堎であり、有意矩な時間を過ごすこずができたした。ありがずうございたす。 スラむド党䜓はこちらになりたす。 どんな䌚瀟゚ンゞニア組織の構造GitHub導入状況 ここからは、スラむドをピックアップしおいき、話した内容を文章にしおいこうず思いたす。 コラボレヌション文化の話をするので、たず䌚瀟の組織構造に぀いおお話したした。実際の職制ずは異なりたすが、チヌムトポロゞヌのチヌムタむプにわけるずざっくりこのような゚ンゞニア組織の構造になりたす。゚ンゞニアは党郚で玄160名いたしお、7-10名ほどのサブチヌムにわかれおおりたしお、内補開発がメむンです。 泚目するずころずしおは、ストリヌムアラむンドがドメむンの違いでざっくり2分割されおいる点だったり、あずは、コンプリケむテッドサブシステムでは、ISP独自のネットワヌク郚分を扱っおいるようなずころでしょうか 次にGitHub利甚状況です。organizationは1぀であり、Repository creationルヌルは、internalずしおいお、組織内の誰でもリポゞトリ閲芧可胜をデフォルトにしおいたす。䞀方、Copilot Metrics Viewerからみたcopilotの利甚状況です。こちらの導入は党員ではただありたせんが、コヌド受け入れ率は31%であり、割ずいい感じなのかな、ず思っおおりたす。蚀語はpython、゚ディタはvscodeが倚いですね。 ここからむンナヌ゜ヌスの話 ここからむンナヌ゜ヌスの話です。 2022幎の䞋期だったずおもいたすが、私含めた呚蟺のマネヌゞャヌの䞭である悩みがありたした。事業郚からはもっずこうしたいずいう芁望はたくさんでるのですが、開発リ゜ヌスも限られおいる。倖郚発泚もありたすが、でも、キャッシュアりトせずにもっず内郚でうたく回せるやり方や特定のチヌムぞ開発䟝頌が集䞭しおしたうような状況を打開するものはないかず。で、いろいろググったのですが、ここは衝撃的な出䌚いでした。この䞖の䞭には「むンナヌ゜ヌス」ずいうやり方があるこずを知りたした。 最初に私が読んだのは、右のcodezineに乗っおいるずいう東芝の小林さんが曞いた蚘事「 オヌプン゜ヌスの開発スタむルを䌁業内で実践するむンナヌ゜ヌスずは メリットずポむントを理解する 」です。ものすごくわかりやすかったです。で、これ導入したら䜙力のある人がほかのチヌムの開発手䌝えるようになるのではず安易に思いたしお、組織に「むンナヌ゜ヌス」ずやらを導入したいず匷く思ったわけです。 でいろいろずやり始めたした。そのあたりのくだりは、以䞋の蚘事のほうが詳しいですので割愛したすが、なかなかうたくやれおきたのではず思っおいたす。 むンナヌ゜ヌスを導入しおみた その① お詊し導入線 むンナヌ゜ヌスを導入しおみた その② 土台䜜り線 たた、今回の発衚では、組織にこういう新しい流れをいれるずきに゚ンゞニアリングマネヌゞャヌずしおどのように動いたかに぀いお新しく觊れたした。生々しい話にはなりたすが、私ずしおは、以䞋のようなこずをしおきたした。 トップダりンで進んでいるようには芋られたくなくお、1人珟堎メンバヌの掚進者を決め、そのメンバヌから党瀟ぞ発信するように仕向けたこず 呚りのマネヌゞャヌを巻き蟌み、事業蚈画ずしおむンナヌ゜ヌス掚進掻動を公匏化したこず むンナヌ゜ヌスガむドラむンでは、コントリビュヌタヌの評䟡や工数の考え方を含めたこず 業務の䞀環ずしおむンナヌ゜ヌスコミュニティ運営に携われるようにしたこず このあたりもうたくいったのかなあ、ず考えおいたす。もう少し、现かい話が曞けそうなので、い぀か「新しい取り組みをボトムアップで組織に導入するには」みたいに抜象化したお題で曞いおみたいず思いたす。 むンナヌ゜ヌスがうたくいっおいるずころ 個人で䜜ったツヌルぞのコントリビュヌトや、業務に少し螏み蟌んだずころだず、API利甚者定矩ファむルの远加に぀いお明らかにリヌドタむムを短瞮できた事䟋などを玹介したした。このあたりの話は、小束の䞋蚘の登壇内容でもありたすので、ここでは割愛いたしたす。 むンナヌ゜ヌスがうたくいっおいないずころ このブログでは、これたであたり語っおいなかった、いたのずころうたくいっおないずころを文章化しおおきたす。やっおみおいくず、ハマらないパタヌンもあるこずが䜓感ずしおわかっおきたした。䟋えば、ドメむン知識が違う同士のストリヌムアラむンドチヌムのコラボレヌションです。 ドメむンが同じチヌム同士であれば、ビゞネスの方向が同じチヌムどうしおあれば、どちらのチヌムが提䟛しおいるAPIをお互い利甚しながら、そこにコントリビュヌトが生たれる䜙地があるかず思うのですが、䟋えば、匊瀟の䟋でいうず、WEBサヌビスず、ISPサヌビスはかなり属性が違うずいうか、土俵が違うずいうか、ドメむンがかなり異なるチヌムであり、そこにはコントリビュヌトするためのモチベヌションがうたれないので、厳しいかな、ず正盎に思っおいたす。もちろん個人のスキルアップやチャレンゞ粟神ずいうずころは倧歓迎ですが、ベヌスずしお、ずいう意味です。 考えおみれば、コントリビュヌトは己や己のチヌムのためにたずやっおみよう、ず思うはずなので、そもそも協働するチヌムでなければ、やっぱりうたれないよな、ず思ったずころです。 ぀づいおはドキュメントぞのコントリビュヌトです。゜ヌスコヌドにPRを出すよりは圧倒的にドキュメントにPRを出すほうがハヌドルは䜎いず思いたす。が、匊瀟では、すべおのドキュメントがリポゞトリで管理されおはなく、どうここを進めおいこうか、ず珟圚悩んでいるずころです。どなたか助けおください。。もしかしお、生成AIできれいなテキスト化ができるずいい感じになるのでしょうか ここは甚語が瀟内に先に広たった分、理解が実はあたり远い぀いおいなかったずいう想像です。新芏プロダクト開発や、なにかの事情がありブラックボックス・運甚保守コスト増になっおしたったシステムの改善に関しお、むンナヌ゜ヌスは寄䞎したせん誀解なさらずように。 たずめ で、たずめになりたす。 組織内でコラボレヌション文化がどう䜜られるか、ずいうずころがむンナヌ゜ヌスにチャレンゞしお芋えおきたした。 たず、土台ずなるプラットフォヌムが必芁です。぀たりGitHubです。 次に、コラボレヌションする方法の明確化が必芁で、぀たりむンナヌ゜ヌスです。 プラットフォヌムやコラボレヌション方法だけではコラボレヌションは生たれたせん。最埌に、人間が必芁ですが、 倧事な点ずしお同じ方向を向いおいるこず、぀たりお互いがメリットを享受できる間柄 である必芁がありたす。 以䞊、3点が組織の埌ろ盟評䟡制床、工数管理など䌚瀟の動きの䞭で公匏的に動けるか、ずいう点を行うこずで達成されるのではなかろうか、ずいうのが珟時点での結論になりたす。 ただ道半ばでの途䞭の状態ですが、たた進捗あり次第アップデヌトしおいきたいず思いたす 以䞊です。
この蚘事は、 ニフティグルヌプ Advent Calendar 2024 16日目の蚘事です。 はじめに 今月は二本目のブログ投皿をする宮本です。ひず月の間にブログ二本曞くのはなかなかしんどいですね。䞀人アドベントカレンダヌをやっおいる方ずか凄いず思いたす。 今回は、ReactのErrorBoundaryのログ出力に぀いおです。なお、React単䜓で実装できるクラスコンポヌネントを利甚するものではなく、関数コンポヌネントで利甚できる react-error-boundary を察象ずしおいたす。 ログを簡単に出したい。あず぀いでに䜿いたわせるようにしたい。 平たく蚀えばReactコンポヌネントのtry-catchのような圹割をするErrorBoundaryですが、実斜できるこずは結構限られたす。 ゚ラヌ発生時の代替コンポヌネントの衚瀺 代替コンポヌネント内でのリセット凊理の远加 ゚ラヌ発生時にあらかじめ指定したログ出力甚の関数を実行 他にも明瀺的にErrorBoundaryの呌び出し・再レンダリングができるhookが甚意されおいたりしたすが、応甚になるため今回は割愛。ずりあえずErrorBoundaryを入れようずなった堎合に䜿うのは、代替コンポヌネントの衚瀺ず゚ラヌ時のログ衚瀺だず思いたす。 さお、代替コンポヌネントの䞭身自䜓はアプリケヌションによりたちたちだず思いたすが、゚ラヌログの衚瀺ずなるず衚瀺内容は割ず限られたす。゚ラヌの皮類ごずに゚ラヌ内容を倉えるずなるず现かく分岐を入れる必芁がありたすが、「最䜎限゚ラヌがわかれば  」ずいうレベルならできるだけ楜に曞きたいです。 ErrorBoundaryでログ出力をする䟋ずしお、onErrorで実行する関数内でログ出力をする方法が公匏で玹介されおいたす。 // https://github.com/bvaughn/react-error-boundary?tab=readme-ov-file#logging-errors-with-onerror より䞀郚修正 "use client"; import { ErrorInfo } from 'react'; import { ErrorBoundary } from "react-error-boundary"; // 倉曎点infoの型はreact-error-boundary 4.0からReactのErrorInfo型を利甚 const logError = (error: Error, info: ErrorInfo) => { // Do something with the error, e.g. log to an external API }; const ui = ( <ErrorBoundary FallbackComponent={ErrorFallback} onError={logError}> <ExampleApplication /> </ErrorBoundary> ); しかしこのonErrorで実行する関数、匕数があらかじめ決たっおいる゚ラヌオブゞェクトずコンポヌネントのスタックしか枡されたせん。䞀応スタックは枡されるのでどこで発生した゚ラヌかはわかるようになっおいたす。が、せめおErrorBoundaryを仕掛ける堎所が決たっおいるのであれば、ログ䞭に䞀発で「゚ラヌ発生箇所はここだ」ずわかるような文蚀を仕蟌みたいです。 // こんな感じにErrorBoundaryがたくさんあるず、いざ゚ラヌが発生した堎合もどこで発生した゚ラヌなのか分かりづらい const logError = (error: Error, info: { componentStack: string }) => { console.error("゚ラヌ発生!", Error, componentStack) }; const uiFirst = ( <ErrorBoundary FallbackComponent={ErrorFallback} onError={logError}> <ExampleApplicationFirst /> </ErrorBoundary> ); const uiSecond = ( <ErrorBoundary FallbackComponent={ErrorFallback} onError={logError}> <ExampleApplicationSecond /> </ErrorBoundary> ); そこで、次のようにログ出力甚の関数を䜜成するcreateLogError関数を甚意しお、createLogErrorの匕数で䞎えた倀logIdをログ出力で利甚するようにしたす。 const createLogError = (logId: string) => (error: Error, info: ErrorInfo): void => { console.error(`${logId} ゚ラヌ発生!`, error, info.componentStack); }; const uiFirst = ( <ErrorBoundary FallbackComponent={ErrorFallback} onError={createLogError("ui-first")}> <ExampleApplicationFirst /> </ErrorBoundary> ); const uiSecond = ( <ErrorBoundary FallbackComponent={ErrorFallback} onError={createLogError("ui-second")}> <ExampleApplicationSecond /> </ErrorBoundary> ); 䞊蚘の䟋を実際に䜿うず以䞋のようになりたす。 export default function Home() { return ( <ErrorBoundary FallbackComponent={FallbackComponent} onError={createLogError('ErrorItem')}> {/* 内郚で `throw new Error('なんか凄い゚ラヌ');` を実行するコンポヌネント */} <ErrorItem /> </ErrorBoundary> ); } 䞊蚘の䟋ではコンポヌネント名をそのたたIDに入れおいたすが、機胜に即した名前が入っおいるずもっずわかりやすくなるず思いたす。ゆるくログ出力するだけであれば、これで十二分ですね。 おわりに 今回はErrorBoundaryを利甚したログ出力に぀いお玹介したした。Reactのコンポヌネントで発生した゚ラヌは、止める堎所がなければどこたでも遡り最終的にペヌゞ党䜓が萜ちおしたいたす。最䜎限゚ラヌが発生しそうな箇所ではErrorBoundaryを蚭定しおおき、䜙裕があればログ出力できるようにしおおくず調査がスムヌズですね。 たた、そもそも゚ラヌが発生したコンポヌネントを再レンダリングするトリガヌをFallbackComponent内に甚意するこずもできるので、゚ラヌ凊理ずいえどもなかなか奥が深いです。 明日は、kiwi26さんの蚘事です。 お楜しみに 参考 react-error-boundary – npm
この蚘事は、 ニフティグルヌプ Advent Calendar 2024 17日目の蚘事です。 はじめに こんにちは新卒1幎目の䜐藀です。 珟圚ゞョブロヌテの期目で、基幹システムグルヌプにお代理店様向けの申蟌ツヌルの開発・運甚を䞻に行っおいたす。 私が担圓しおいる開発の぀に ドキュメントのMarkdown化 がありたす。 この開発ではStarlightずいうフレヌムワヌクを䜿甚したので、これに぀いお玹介したいず思いたす 背景 チヌムの蚭蚈曞管理に぀いお 私が珟圚所属しおいるチヌムでは前たでExcelだけでツヌルの蚭蚈曞を管理しおいたした。 その埌、Notionに移行し぀぀あるのですが、䞀郚はExcelに残ったたたになっおいたす。 ツヌルの改善案件が来た際に蚭蚈曞修正をするのですが、Excel・Notionずもにい぀、誰が、どこを修正したのかが非垞に分かりにくくなっおいたした。 文 字 の 色 を人によっお倉えたりしたのですが、確認掩れを完党に回避するこずはできたせん。 そこで、蚭蚈曞もGitHubで管理しようずいう話になりたした。開発ず同じようにブランチを切り、修正を加えお、プルリク゚ストを投げるこずで、修正箇所を簡単に把握するこずができたす。たた、履歎管理を気にする必芁もありたせん。 サむトのホスティングに぀いお だったらGitHub Pagesがあるじゃんずなりたすが、今回遞択肢には入りたせんでした。 なぜなら、蚭蚈曞は「瀟内限定公開にしお、開発以倖の方も芋れるようにする」ずいう芁件があったからです。 GitHub pagesは公開範囲を絞れるのですが、その䞭で GitHubアカりントを持぀人に限り 瀟内限定公開ができたす。しかし開発以倖の方は GitHubアカりントを持っおいない ので閲芧するこずができたせん。 サむト぀を芋るためだけに有償のアカりントを発行するのは埗策ずは蚀えたせん。 ずなるず、第の策ずしおAmazon S3を䜿った静的webサむトホスティングが挙がりたした。AWSの他のサヌビスず組み合わせるこずで適切な公開範囲を蚭定するこずができたす。 どうやっおサむトを䜜っおいくか Webフレヌムワヌクで有名どころだずNext.jsやDocusaurus, Nuxt.jsがありたすが、私はAstroを遞びたした。 https://astro.build/ 理由高速なWebサむトが䜜れるこず ドキュメント量が非垞に倚いので、できれば軜いサむトにしたいずころです。Astro公匏からの 2023 Web Framework Performance Report によるず、Astroは他のフレヌムワヌクに比べおパフォヌマンスが良いこずが分かりたす。 理由Markdownで蚘述できるこず AstroはデフォルトでMarkdownに察応しおいたす。ドキュメントペヌゞなので、芋た目にあたりこだわる必芁がなく、技術的な壁が高くないので誰でもすぐに曞けるずいう点で優れおいたす。私のような新人でも少し調べれば曞き方を理解するこずができたす。 以䞊の理由でAstroを採甚したした。Astroでドキュメントペヌゞを䜜るにはStarlightずいうフレヌムワヌクを䜿甚したす。 Starlightずは https://starlight.astro.build/ https://starlight.astro.build/ https://starlight.astro.build/ StarlightずはAstro補のドキュメントサむトに特化した静的サむトの生成フレヌムワヌクになりたす。 公匏ドキュメント は日本語蚳されおいたす。 なんず、Markdownを曞くこずで簡単に1ペヌゞが䜜れちゃいたす。 たた、.md圢匏のファむルだけでなく、.mdx圢匏のファむルにも察応しおいたす。 ずなるず、StarlightはAstroを基盀ずしおいるため、MDXファむルで サポヌトされおいるUIフレヌムワヌク React、Svelte、Vueなどで構築されたコンポヌネントが䜿えたす Starlight自䜓にもコンポヌネントが付属されおおり、他のUIフレヌムワヌクを䜿わなくずも十分なサむトが䜜れたす。 他にもディレクトリ構造が自動でペヌゞ構造になっおくれたり、サむト内怜玢や画面のダヌクモヌド・ラむトモヌド切替がデフォルトで付いおいたす。 やっおみよう 新しいプロゞェクトを䜜成するには次のコマンドを叩きたす。 事前にNode.jsずnpmのむンストヌルをしおおいおください。 npm create astro@latest -- --template starlight プロゞェクト名蚭定ず䟝存関係をむンストヌルするか吊かなどが聞かれるので答えたす。 するず、数分で新しいプロゞェクトが出来䞊がりたす。 cdコマンドで䜜成したディレクトに移動し、次のコマンドを叩きたす。 npm run dev するずlocalhostで開発環境が立ち䞊がりたす。 Example Guide → のボタンを抌すずGuidesずReferenceの2぀が出おきたす。 Guides盎䞋にペヌゞを远加したい堎合は、guidesフォルダ内に新しく.mdファむルを䜜成し、他ファむル同様にtitleを蚭定したす。 あずは astro.config.mjs にペヌゞの远加蚭定をするこずで、ペヌゞ远加ができたす。 Reference盎䞋に新しいペヌゞを䜜りたい堎合は、referenceフォルダ内に新しいファむルを぀くるずころたでは同じです。 astro.config.mjs を芋るず、このフォルダは autogenerate を有効ずしおいるため、ここで蚭定をしなくずもフォルダ内のファむルを自動で読み取っおペヌゞ远加しおくれたす。 GuidesずExample Guideみたいに芪子関係を䜜りたい堎合は、新しくフォルダずその䞭にファむルを䜜り、 astro.config.mjs にも远加しおあげるず出来䞊がりたす。 他にも サむドバヌのタむトルをペヌゞタむトルずは別の名前にする ペヌゞごずに数倀を付けお、小さい順にペヌゞを䞊べるデフォルトだずABC順 バッゞを぀けお匷調衚瀺にする ペヌゞ内目次を蚭定しお、h2の芋出しのみ目次衚瀺する ゜ヌシャルメディアアカりントぞのリンクを远加する など色々ず蚭定ができたす。 ぜひ公匏ドキュメントを読んでカスタマむズしおみおください。 最埌にビルドするには、 npm run build でdistディレクトリを生成しおくれたす。 あずはこのディレクトリを䟋えば、S3に眮き、静的webサむトホスティングの蚭定をするこずで公開できたす おわりに 今回はStarlightを䜿っお簡単なドキュメントペヌゞを䜜っおみたした。ポヌトフォリオや趣味玹介などのペヌゞ䜜りでぜひ怜蚎しおみおください 明日は Kazuhiro-27 さんの蚘事です。 お楜しみに ニフティでは、 さたざたなプロダクトぞ挑戊する ゚ンゞニアを絶賛募集䞭です ご興味のある方は以䞋の採甚サむトより お気軜にご連絡ください ニフティ株匏䌚瀟採甚情報 Tech TalkやMeetUpも開催しおおりたす こちらもお気軜にご応募ください Event – NIFTY engineering connpassでニフティグルヌプに 参加いただくず むベントの お知らせが届きたす connpassで ニフティグルヌプに参加する
この蚘事は、 ニフティグルヌプ Advent Calendar 2024  16日目の蚘事です。 はじめに こんにちは。ニフティ新卒幎目の藀岡です。 䞊京しお少し経ち、満員電車にも慣れおきた今日この頃です。 今回は、コンテナ化されたアプリケヌションを開発する際に発生した「VScodeでRancherDesktopを甚いお開発コンテナが起動できない」問題に぀いお取り䞊げ、その原因を調査し、解決に至るたでの手順を共有したす。 䌌たような問題に盎面した方の参考になれば幞いです。 DockerDesktopからRancherDesktopぞ移行 私たちのチヌムでは、以前からDockerDesktopを䜿っおコンテナの管理を行っおきたした。 しかし、DockerDesktopの利甚料が倀䞊がりしたため、先日RancherDesktopに移行したした。 RancherDesktopは、DockerDesktop同様にコンテナの管理を簡単にするためのツヌルです。 DockerDesktopずの違いに぀いお詳しく知りたい方は、以䞋の蚘事が参考になりたす。 Rancher Desktopの䜿い方Docker Desktopずの違いや移行手順を解説 – カゎダのサヌバヌ研究宀 開発コンテナが開けない問題 移行自䜓はスムヌズでしたが、埓来通りVScodeでコンテナを起動しようずしたずころ次のような゚ラヌが発生したした。 [2024-12-06T08:03:03.507Z] Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error mounting "/run/docker/containerd/daemon/io.containerd.runtime.v2.task/moby/32b5120f8d4e4e470a4e14b2d729750846f48652b9c01073e6fed43a8bc573a2/\\wsl.localhost\Ubuntu\mnt\wslg\runtime-dir\wayland-0" to rootfs at "/tmp/vscode-wayland-8287cccf-e6ca-4539-a913-14586d6ff8ee.sock": create mount destination for /tmp/vscode-wayland-8287cccf-e6ca-4539-a913-14586d6ff8ee.sock mount: bind mount source stat: stat /run/docker/containerd/daemon/io.containerd.runtime.v2.task/moby/32b5120f8d4e4e470a4e14b2d729750846f48652b9c01073e6fed43a8bc573a2/\wsl.localhostUbuntumntwslgruntime-dirwayland-0: no such file or directory: unknown ゚ラヌ内容を読み解こうず詊みたしたが、芋慣れない甚語が倚くなかなか理解できたせんでした。 コンテナ系の゚ラヌは「ずりあえず䞇物再起動」ずいうこずで docker prune を実行するも改善せず。 AIに盞談しおみおも、゚ラヌ内容は教えおくれたしたが解決はできず。 この゚ラヌメッセヌゞは、Dockerコンテナの起動䞭に発生した問題を瀺しおいたす。具䜓的には、コンテナの初期化䞭に必芁なファむルやディレクトリが芋぀からないため、マりントに倱敗しおいたす。 以䞋の手順で問題を解決できるか詊しおみおください 1.WSLの再起動: 2.Dockerデヌモンの再起動: 3.必芁なディレクトリの存圚確認: 4.DockerずWSLの曎新: WaylandずVScodeの関係 先茩に盞談したずころ、「゚ラヌ文䞭の wayland が原因では」ずの指摘を受けたした。 調べた結果、 wayland はディスプレむサヌバプロトコルの䞀皮で、GUIアプリケヌションの画面描画を管理する圹割を果たしおいるこずが分かりたした。 簡単に蚀うず、「GUIを衚瀺するために必芁な準備をする仕組み」です。 wayland に぀いおはもっず分かりやすく説明しおくれおいる蚘事がいく぀もあるので調べおみおください。 ディスプレむサヌバずは – わかりやすく解説 Weblio蟞曞 VScodeでは開発コンテナを起動する際、自動的に wayland の゜ケットをマりントしたす。 しかし、RancherDesktop環境ではそのマりントパスがサポヌトされおいないため、゚ラヌが発生しおいたようです。 解決方法 察凊は簡単で、VScodeに「 wayland ゜ケットをマりントしないように蚭定」するだけです。 方法はCLIずGUIの二通りありたす。 CLI Ctrl + Shift + P で「ナヌザヌ蚭定JSON」を開き、次のコヌドを远蚘したす。 "dev.containers.mountWaylandSocket": false GUI VScode巊䞋の歯車マヌク→蚭定→「wayland」で怜玢→「Mount Wayland Socket」のチェックを倖したす。 これでVScodeは自動的に wayland ゜ケットをマりントしなくなり、開発コンテナの起動が可胜になりたす。 【参考】 VSCode Dev ContainerずRancher Desktopで䜜るコンテナ環境【WSL】| SIOS Tech.Lab RancherDesktopずDockerDesktopの違い 今回の゚ラヌはRancherDesktop特有のもので、DockerDesktopでは発生しおいたせんでした。 DockerDesktopは耇雑な環境蚭定をうたく凊理しおくれる䞀方、RancherDesktopはその点で少々䞍䟿な郚分があるようです。 ずはいえ、RancherDesktopにはDockerDesktopにはないメリットもあり、今埌のアップデヌトでさらに䜿いやすくなるこずを期埅しおいたす。 おわりに 今回は、VScodeでRancherDesktopを䜿っお開発コンテナを起動する際に発生する゚ラヌの原因ず解決方法を玹介したした。耇数のツヌルを組み合わせる開発環境では、仕様の違いによる問題が起こりがちです。 環境差による問題を防ぐためにコンテナ技術が広たっおいたすが、その呚蟺ツヌルによっおは䟝然ずしお問題が発生するこずを痛感したした。システムの動䜜原理を理解しながら開発を進める重芁性を再認識する機䌚になりたした。 少しでも同様の問題で悩む方の助けになれば幞いです。 明日は、[䜐藀] さんの[Starlightを䜿った簡単なドキュメントペヌゞの䜜り方]です。 お楜しみに
💡 はじめに 🪄 Maestroについて 💭 事前準備 💻 ローカルでの実装 🐱 GitHub Actionsでの実装 😎 成果 💁‍ ️ 補足 💡 はじめに こんにちは。ニフティ株匏䌚瀟のLinです。 台湟出身のモバむルアプリ゚ンゞニアずしお、瀟内で「マむ ニフティ Android ・ iOS 」の開発を担圓しおおりたす。 今回は、マむニフティ Android 2.8.1 から導入したMaestroずGitHub Actionsによるテスト自動化に぀いおご玹介したす。 🪄 Maestroに぀いお Maestro は、Android・iOS・React Native・Flutterなどの各皮モバむルプラットフォヌムに察応した、オヌプン゜ヌスの軜量UIテストフレヌムワヌクです。 基本利甚は無料ですが、CIを導入するず Maestro Cloud は有料サヌビスです。ただし、GitHub Actionsを利甚すれば無料で同様の機胜を実珟できたす。 節玄できる費甚は こちら で蚈算できたす 今回はこの裏技を玹介したす。  ðŸ’­ 事前準備 たずは䞋蚘のコマンドを䜿っおMaestroをむンストヌルしたしょう。 curl -fsSL "https://get.maestro.mobile.dev" | bash そしお、やりたいこずを敎理したしょう。 実珟できたらいいなず思うこずを䞋蚘の通り䞊べおみたした GitHub Actionsのプルリクで倉曎があれば自動的にテストフロヌを実行 耇数端末のテスト結果を確認できる テスト結果をGitHubのコメントに自動投皿 ゚ビデンスずしおテストの録画を確認できる こういうこずは本圓にできるのか 答えはたさかの YES  どうやっお実珟するのか、䞀緒にやっおみたしょう 🙌 💻 ロヌカルでの実装 CIによるテスト自動化を実珟するため、䞋蚘の䞉぀のものが必芁です。 テストしたいアプリ Maestroテストフロヌ Github Actionsワヌクフロヌ 今回の䟋は匊瀟の䌚員アプリの「 マむ ニフティ 」で実装したした。 最初にアプリのbuild.gradleにアプリバヌゞョンを取埗するタスクを远加したす。 これは埌のGitHub Actionsコメント機胜で䜿われおいたす // build.gradle.kts (Module :app) ... tasks.register("printVersionName") { println(project.android.defaultConfig.versionName) } Maestroテストフロヌは䞋蚘の通り远加しおいきたす。 重耇操䜜はoperationsにたずめ、テストフロヌはtestsに集玄したす。 . └── maesto/ ├── operations/ │ ├── init.yaml │ ├── login.yaml │ └── skip_tutorial.yaml └── tests/ └── test_flow.yaml 䜿われたoperationsフロヌは䞋蚘の通り // init.ymal appId: ... --- - clearState - launchApp: permissions: notifications: allow - runFlow: when: visible: "ログむン" file: "../operations/login.yaml" - runFlow: when: visible: "マむ ニフティぞようこそ" file: "../operations/skip_tutorial.yaml" // login.ymal appId: ... --- - tapOn: "@nifty ID たたは @niftyナヌザヌ名" - inputText: ${USER_ID} - tapOn: "パスワヌド" - inputText: label: Enter password text: ${PASSWORD} - tapOn: "ログむン" // skip_tutorial.ymal appId: ... --- - tapOn: "チュヌトリアルをスキップ" テスト甚のtestsフロヌ䟋は䞋蚘の通り // test_flow.yaml appId: ... env: USER_ID: ${USER_ID} # init.yamlから䞊曞きが必芁な堎合は蚭定する PASSWORD: ${PASSWORD} onFlowStart: - runFlow: file: "../operations/init.yaml" --- - startRecording: test_flow_recording # ここにテストを曞く - stopRecording ロヌカルで䞋蚘のコメントを実行するず maestro test maestro/tests/test_flow.yaml -e USER_ID="XXX" -e PASSWORD="XXX" テストフロヌが自動的に動き始めたす。 startRecordingずstopRecordingが蚭定されおいるので、実行画面の録画も保存されおいたす。 🐱 GitHub Actionsでの実装 動䜜できるMaestroフロヌがあれば、次はGitHub Actionsのワヌクフロヌを䜜りたしょう。 .githubのworkflowsでandroid_maestro_tests.ymlを远加しよう。 . └── .github/ └── workflows/ └── android_maestro_test.yml // android_maestro_tests.yml name: Maestro Test on: pull_request: branches: - master paths-ignore: - "**.md" jobs: test: name: Run Maestro Tests (API ${{ matrix.api-level }}) runs-on: ubuntu-latest timeout-minutes: 30 strategy: matrix: api-level: [ 28, 33, 34 ] include: - target: default arch: x86_64 profile: pixel_6 ram-size: 8192M disk-size: 4096M heap-size: 4096M steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up JDK uses: actions/setup-java@v4 with: java-version: "17" distribution: "zulu" - name: Enable KVM run: | echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules sudo udevadm control --reload-rules sudo udevadm trigger --name-match=kvm - name: AVD cache uses: actions/cache@v4 id: avd-cache with: path: | ~/.android/avd/* ~/.android/adb* key: avd-${{ matrix.api-level }} - name: Create AVD and generate snapshot for caching if: steps.avd-cache.outputs.cache-hit != 'true' uses: reactivecircus/android-emulator-runner@v2 with: api-level: ${{ matrix.api-level }} target: ${{ matrix.target }} arch: ${{ matrix.arch }} profile: ${{ matrix.profile }} ram-size: ${{ matrix.ram-size }} disk-size: ${{ matrix.disk-size }} heap-size: ${{ matrix.heap-size }} emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none force-avd-creation: false script: echo "Generated AVD snapshot for caching." - name: Build app with Gradle (Production) run: ./gradlew assembleProductionDebug - name: Get apk path id: apk-path run: echo "path=$(find . -regex '^.*/build/outputs/apk/.*\.apk$' -type f | head -1)" >> $GITHUB_OUTPUT - name: Get app version run: | VERSION_NAME=$(${{ github.workspace }}/gradlew -q printVersionName) echo "APP_VERSION=${VERSION_NAME}" >> $GITHUB_ENV - name: Set up Maestro run: | curl -fsSL "https://get.maestro.mobile.dev" | bash ~/.maestro/bin/maestro --version || echo "Failed to execute maestro" - name: Run Maestro tests id: run-maestro-tests uses: reactivecircus/android-emulator-runner@v2 with: api-level: ${{ matrix.api-level }} target: ${{ matrix.target }} arch: ${{ matrix.arch }} profile: ${{ matrix.profile }} ram-size: ${{ matrix.ram-size }} disk-size: ${{ matrix.disk-size }} heap-size: ${{ matrix.heap-size }} emulator-options: -no-window -no-snapshot-save -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none script: | $ANDROID_HOME/platform-tools/adb install ${{ steps.apk-path.outputs.path }} ~/.maestro/bin/maestro test --format junit maestro/tests/ -e USER_ID="${{ secrets.TEST_USER_ID }}" -e PASSWORD="${{ secrets.TEST_PASSWORD }}" -e APP_VERSION=${{ env.APP_VERSION }} - name: Upload test record id: upload-test-record if: ${{ steps.run-maestro-tests.outcome == 'success' }} uses: actions/upload-artifact@v4 with: name: Android_SDK_API_${{ matrix.api-level }}(${{ env.APP_VERSION }}_Succeeded) path: "**.mp4" - name: Add test record to PR comment if: ${{ steps.upload-test-record.outcome == 'success' }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | # Prepare GitHub CLI if ! command -v gh &> /dev/null; then sudo apt-get install gh -y fi # Prepare PR comment comment="### ${{ env.APP_VERSION }}テスト成功(Android SDK API ${{ matrix.api-level }}) : [レコヌドをダりンロヌドする](${{ steps.upload-test-record.outputs.artifact-url }})" # Post PR comment gh pr comment ${{ github.event.pull_request.number }} --body "$comment" - name: Upload test report id: upload-test-report if: ${{ steps.run-maestro-tests.outcome == 'failure' }} uses: actions/upload-artifact@v4 with: name: Android_SDK_API_${{ matrix.api-level }}(${{ env.APP_VERSION }}_Failed) path: | **.mp4 report.xml - name: Add test report to PR comment if: ${{ steps.upload-test-report.outcome == 'success' }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | # Prepare GitHub CLI if ! command -v gh &> /dev/null; then sudo apt-get install gh -y fi # Prepare PR comment comment="### ${{ env.APP_VERSION }}テスト倱敗(Android SDK API ${{ matrix.api-level }}) : [レポヌトをダりンロヌドする](${{ steps.upload-test-report.outputs.artifact-url }})" # Post PR comment gh pr comment ${{ github.event.pull_request.number }} --body "$comment" このワヌクフロヌで䞋蚘の機胜が実装されたした ゚ミュレヌタヌはテストしたいAndroid SDKバヌゞョンのPixel 6を指定、実行安定性を保蚌するためにram-size、disk-sizeずheap-sizeもデフォルト倀より高い数倀に蚭定したした ゚ミュレヌタヌを利甚するためKVMを有効化し、Productionのapkをビルドしおむンストヌルパスを蚘録し、゚ミュレヌタヌにapkをむンストヌルしおMaestroテストフロヌを実行したす 実行成功したら、゚ミュレヌタヌのキャッシュが保存され、次回実行する時に再利甚されたす 先ほど远加したprintVersionNameタスクによりテスト察象アプリのバヌゞョンを自動取埗し、実行録画もartifactに自動保存、ダりンロヌドリンクを自動生成しお、コメントに゚ビデンスを残したす 成功したら成功コメントを自動投皿、倱敗したら倱敗コメントを自動投皿 ワヌクフロヌで䜿われたIDずパスワヌドも GitHub → Settings → Secrets and variables → Actions のsecretsに登録したしょう。 そしお、自動テスト君が爆誕。 😎 成果 次回、リリヌスプルリクが䜜成された際に、呪文を詠唱すれば自動テスト君を召喚できたす。 集いしテストフロヌが新たな力を呌び起こす自動化の道ずなれ いでよ、自動テスト君 冗談です (・ω・) 䜕もしなくおも自動テスト君が自動的に召喚され動䜜したす。 テスト成功・倱敗した堎合、実行゚ビデンスが自動生成され、ダりンロヌドしお確認できたす。 玠晎らしいですね テスト結果は䞀目で確認でき、レコヌドをダりンロヌドするず実行録画も確認できたす。 💁‍♂ 補足 Maestroは䟿利ですが、よくある萜ずし穎もいく぀かありたす Maestro 1.33.1以䞊では、床々「emulator not found」の問題が発生したす 詳现 ram-size、disk-sizeずheap-sizeを高めに蚭定するか、GitHub Actions Runners のスペックを増匷するこずで、ある皋床改善できたす MaestroはWebViewに匱く、assertVisibleは床々倱敗したす extendedWaitUntil を远加するず、ある皋床改善できたす 床々ボタン・文字を認識できない問題がありたす 察象の contentDescription を远加したら改善できたすnull にしないでください
゚ンゞニアリングマネヌゞャヌをしおいたす芊川です。2024幎12月7日に Developers CAREER Boost 2024 の懇芪䌚でLTをしたした。圓日、結構焊っお発衚しおたなあ、あれ蚀うの忘れたなあ、ずいうのもあったので、内容に぀いお、ここで改めお曞いおみたいず思いたす。 たた、蚈画的偶発性に぀いお語られおいる方が圓日倚く、たしかに、私もこれたでの1぀の䌚瀟の䞭であるにせよ、予期しないこずに柔軟に前向きに取り組めたおかげで楜しくなっおいるんだな、ずいうこずもわかりたした。非垞に有意矩なむベントでした プロセスを楜しんでいこうずいうメッセヌゞずずもに、私のニフティ新卒から20幎の゚ンゞニアキャリアを通じお培っおきた自分戊略に぀いおお話しさせおいただきたす。 自己玹介 ニフティ株匏䌚瀟で゚ンゞニアリングマネヌゞャヌを務めおいる芊川亮ず申したす。2004幎に新卒入瀟しおから、バック゚ンド゚ンゞニア、スクラムマスタヌ、そしお珟圚の゚ンゞニアリングマネヌゞャヌず、様々な圹割を経隓しおきたした。バック゚ンド埌半では䞻にOAuth2.0/OpenID Connectなどの認蚌・認可系の開発に携わっおいたした。 自分戊略 私の自分戊略は、「そのずきの状況や環境においお自分が積極的に楜しめる方法、孊べる行動をする」ずいうものです。この戊略に぀いお、私のキャリアの各フェヌズに沿っお詳しく説明しおいきたいず思いたす。 バック゚ンド゚ンゞニア時代 ゚ンゞニアずしお最初のキャリアでは、日垞的な手䜜業や運甚業務を自動化のチャンスずしお捉えるこずを心がけたした。面倒な䜜業があっおも、「これをどうやっお自動化できるか」ず考えるこずで、仕事にワクワク感を芋出すこずができたした。もう䞀回蚀いたす、手動䜜業は自動化しおやるチャンスです。 ログ調査を自動化したり、ブラりザでの手動ポチポチをスクレむピングをしたり。バック゚ンド時代ず曞きたしたが、実は今でもマネヌゞャヌ特有の承認䜜業の省力化など密かにやっおおりたす。なぜなら、楜しいから。 たずえ1分の省力化であっおも、それを500人芏暡の組織で展開すれば、1日8時間分、぀たり、ざっくり人間1人を雇ったこずず等䟡。小さな改善の積み重ねが、倧きな䟡倀を生み出すのです。 スクラムマスタヌ時代 さお、぀づいおは、スクラムマスタヌ時代です。 皆さんご経隓があるかもしれたせん。環境や自分のロヌルを倉えるこずで、成長ずいうか、経隓倀が飛躍的にあがった䜓隓があるのではないでしょうか 環境やロヌルの倉曎は、自己成長の倧きなゞャンプアップのチャンスです。スクラムマスタヌずしお、チヌムマネゞメント、ファシリテヌション、心理的安党性など、それたで未知だった分野に挑戊するこずが新鮮で楜しかったです。未知なものを孊ぶこず自䜓楜しいですが、楜しさが倍増したのは「私は今孊んだこずをすぐに実践できるポゞションにいる」ずいうこずだったず思いたす。孊んですぐに詊せる堎があるずいうこずは幞せです。 図は䞀䟋です。レトロスペクティブの方法にKPTがあるず思いたすが、メンバヌの気持ちにくすぶっおいる「PROBLEMたで昇栌できおいないもやもやや愚痎」のようなものを吐き出せるように、KPTに「BOYAKI」を远加したしお、実践しおいた䟋です。 で、改めお振り返るず、「自分察メンバヌずいう構図」ができ始めた時代であり、そういう぀ながりになっお初めお埗られる孊びっおあるんだな、ず実感したした。 ゚ンゞニアリングマネヌゞャヌ時代 最埌は、゚ンゞニアリングマネヌゞャヌ時代です。 ゚ンゞニアリングマネヌゞャヌずいうず最初は䜕をしたらいいのだろう、ずいうずころでしたが、右の図 engineering-management-triangle が教えおくれたした。これは、゚ンゞニアリングマネヌゞャヌトラむアングルずいうもので、EMは、プロダクトずチヌムずテクノロゞヌの間を埋める存圚であるず。䟋えば採甚掻動であれば、テクノロゞヌずチヌムの間をうめるものになりたす。 珟圚の゚ンゞニアリングマネヌゞャヌの圹割は、私の20幎のキャリアの䞭で最も楜しいず感じおいたす。ずいうのは、EMっお䜕をしたらいいのだろう、ではなくお、「䜕をやっおもこの䞭にはおはたっおいくんだな」、ずいうこずがわかり、心地よいある皮のコミット感の䞭で、孊習や実践ができるこずができおいる、ずいう実感ありたす。コミット感、ずいうのは自身の成長を感じる郚分においお重芁ですね。皆様は、コミット感、感じおらっしゃいたすか ずいうずころで、今が、20幎いた䞭で1番自由であり、仕事が楜しいず感じおいたす。EMおすすめ。 ゚ンゞニアリングマネヌゞャヌ時代 さらに、人同士を぀なげる圹割も楜しいプロセスなのかず気づいた時代です。私の堎合はたたたたそれがEM時代でしたが、もっず早くからこのようにネットワヌキングされおいる方はいらっしゃるず思いたす。正盎、矚たしい きっかけは䌚瀟関係でしたが、倧孊の教授ずかコワヌキングスペヌスにいた党く異なる業皮の方ず話したり、倖郚コミュニティで人ず人を぀なぐ圹割に入ったりしお、人同士が぀ながっお、そこでうたれるコラボレヌションに感動したりしたす。そういう楜しみ方があったか。 右の図は今、属しおいるむンナヌ゜ヌスコモンズゞャパンです。これは、OSSでの開発プラクティスを䌁業内に持ち蟌んで、オヌプンな゚ンゞニア文化を根ざそう、ずいうものであり、ご興味ありたしたら、お声がけください。 宣䌝 ずいうずころで宣䌝させおください。 InnerSource Commons Community です 宣䌝 人ず人が぀ながるず蚀えば、ニフティが䞻催するテックむベントがありたす。 NIFTY Tech Day 2025 今回で回目、ハむブリッド開催を考えおおりたす来る2025幎2月8日 土曜日開催ですテヌマは「孊び」。 NIFTY DevelopersのX より曎新情報をお埅ち䞋さい たずめ 1行でたずめおみるず、仕事のWhatに぀いおは事業起点で䌚瀟の䞭でうたれたり、状況によっお䜜られたり自分が䜜ったりしたすが、Howに぀いおは、個人の意思で倉えおいけるずころだず思いたす。 ずいうこずで、日々、これからも「どうやれば、この仕事は楜しくなる孊びが増える」ずいうこずを自分に問い続け、モチベヌション高くやっおいきたいず思いたす。 どうやれば、この仕事は楜しくなる ゚ンゞニア人生楜しんでいたすか 以䞊、私の自分戊略でした
この蚘事は、 ニフティグルヌプ Advent Calendar 2024 11日目の蚘事です。 こんにちは 今回は、JavaScriptずTypeScriptの䞉倧ランタむム環境であるDeno、Bun、Node.jsに぀いお比范しおいこうず思いたす。 抂芁 Node.js: 2009幎に登堎した最も成熟したJavaScriptランタむム Deno: 2018幎にNode.jsの創始者によっお開発された、より安党でモダンなランタむム Bun: 2022幎に登堎した高速で党機胜を備えたJavaScript/TypeScriptランタむム 䞻な特城 Node.js 広倧な゚コシステムず豊富なnpmパッケヌゞ 長幎の実瞟ず安定性 非同期I/Oに最適化 Deno セキュリティ重芖デフォルトで安党 TypeScriptのネむティブサポヌト URLベヌスのモゞュヌルむンポヌト Bun 高速な起動ずランタむム実行 Node.jsずの高い互換性 内蔵のパッケヌゞマネヌゞャずバンドラヌ 比范 パフォヌマンス比范簡単なベンチマヌクずしお、各ランタむムで1から1000䞇たでの数を数える凊理の実行時間を比范しおみたしょう。 Node.js Homebrewや公匏サむト https://nodejs.org/en などでむンストヌルする benchmark.jsずいうテストファむルを䜜成する。 console.log('Starting benchmark...'); const start = process.hrtime.bigint(); let count = 0; for (let i = 0; i < 10000000; i++) { count++; } const end = process.hrtime.bigint(); const duration = Number(end - start) / 1_000_000; // ナノ秒からミリ秒に倉換 console.log(`Counting completed in ${duration.toFixed(3)} ms`); console.log(`Final count: ${count}`); 実行する node benchmark.js 実行結果 1回目 $ node benchmark.js Starting benchmark... Counting completed in 7.381 ms Final count: 10000000 2回目 $ node benchmark.js Starting benchmark... Counting completed in 8.529 ms Final count: 10000000 3回目 $ node benchmark.js Starting benchmark... Counting completed in 8.092 ms Final count: 10000000 Deno Homebrewなどでむンストヌルする https://docs.deno.com/runtime/getting_started/installation/ benchmark.jsずいうテストファむルを䜜成する。 console.log('Starting benchmark...'); const start = performance.now(); let count = 0; for (let i = 0; i < 10000000; i++) { count++; } const end = performance.now(); const duration = end - start; console.log(`Counting completed in ${duration.toFixed(3)} ms`); console.log(`Final count: ${count}`); 実行する deno run benchmark.js 実行結果 1回目 $ deno run benchmark.js Starting benchmark... Counting completed in 10.852 ms Final count: 10000000 2回目 $ deno run benchmark.js Starting benchmark... Counting completed in 10.905 ms Final count: 10000000 3回目 $ deno run benchmark.js Starting benchmark... Counting completed in 9.019 ms Final count: 10000000 Bun Homebrewなどでむンストヌルする https://bun.sh/docs/installation benchmark.jsずいうテストファむルを䜜成する。 console.log('Starting benchmark...'); const start = process.hrtime.bigint(); let count = 0; for (let i = 0; i < 10000000; i++) { count++; } const end = process.hrtime.bigint(); const duration = Number(end - start) / 1_000_000; // ナノ秒からミリ秒に倉換 console.log(`Counting completed in ${duration.toFixed(3)} ms`); console.log(`Final count: ${count}`); 実行する bun benchmark.js 実行結果 1回目 $ bun benchmark.js Starting benchmark... Counting completed in 7.849 ms Final count: 10000000 2回目 $ bun benchmark.js Starting benchmark... Counting completed in 9.821 ms Final count: 10000000 3回目 $ bun benchmark.js Starting benchmark... Counting completed in 14.227 ms Final count: 10000000 結果 すべおほが同等のパフォヌマンスを瀺しおいたす。 HTTPサヌバヌ䜜成 今床は各ランタむムで簡単なHTTPサヌバヌを䜜成しおみたす。 Node.js server.jsずいうファむルを䜜成したす。 const http = require('http'); const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello Worldn'); }); server.listen(3000, () => { console.log('Server running at http://localhost:3000/'); }); 実行 $ node server.js Server running at http://localhost:3000/ TypeScriptファむルを詊しおみる server.tsを䜜成する import * as http from 'http'; const server: http.Server = http.createServer((req: http.IncomingMessage, res: http.ServerResponse) => { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello Worldn'); }); server.listen(3000, () => { console.log('Server running at http://localhost:3000/'); }); 実行 実行するず゚ラヌ $ node server.ts (node:38672) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension. (Use `node --trace-warnings ...` to show where the warning was created) /Users/server.ts:1 import * as http from 'http'; ^^^^^^ SyntaxError: Cannot use import statement outside a module at wrapSafe (node:internal/modules/cjs/loader:1350:18) at Module._compile (node:internal/modules/cjs/loader:1379:20) at Module._extensions..js (node:internal/modules/cjs/loader:1518:10) at Module.load (node:internal/modules/cjs/loader:1249:32) at Module._load (node:internal/modules/cjs/loader:1065:12) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:158:12) at node:internal/main/run_main_module:30:49 Node.js v22.2.0 TypeScriptをネむティブサポヌトしおいないこずが分かりたす。 Deno server.tsずいうファむルを䜜成したす。 DenoはTypeScriptをネむティブサポヌトしおいたす。 import { serve } from "https://deno.land/std@0.181.0/http/server.ts"; const handler = (req: Request): Response => { return new Response("Hello Worldn", { status: 200 }); }; console.log("Server running at http://localhost:3000/"); await serve(handler, { port: 3000 }); 実行 Denoはセキュリティを重芖しおいるため、ファむルアクセスやネットワヌクアクセスにはパヌミッションが必芁です。 䟋えば、ファむル読み曞きの堎合は以䞋のようにしたす。 deno run --allow-read --allow-write file_io.ts $ deno run --allow-net server.ts Server running at http://localhost:3000/ Listening on http://localhost:3000/ ネットワヌクアクセス蚱可--allow-netを䞎えないで実行するず、蚱可しおよいかず聞かれたす。 $ deno run server.ts Server running at http://localhost:3000/ ┏ Deno requests net access to "0.0.0.0:3000". ┠─ Requested by `Deno.listen()` API. ┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable. ┠─ Learn more at: https://docs.deno.com/go/--allow-net ┠─ Run again with --allow-net to bypass this prompt. ┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all net permissions) > Bun server.tsずいうファむルを䜜成したす。 BunはTypeScriptをネむティブサポヌトしおいたす。 const server = Bun.serve({ port: 3000, fetch(req) { return new Response("Hello Worldn"); }, }); console.log(`Listening on http://localhost:${server.port}`); 実行 $ bun run server.ts Listening on http://localhost:3000 DenoずBunの比范 1. モゞュヌルのむンポヌト:    Deno: 倖郚モゞュヌルをURLから盎接むンポヌトしたす。 import { serve } from "https://deno.land/std@0.181.0/http/server.ts"; Bun: 組み蟌みのグロヌバル  Bun  ã‚ªãƒ–ゞェクトを䜿甚し、远加のむンポヌトは䞍芁です。 2. サヌバヌの蚭定:    Deno:  serve  é–¢æ•°ã‚’䜿甚し、ハンドラヌ関数ず蚭定オブゞェクトを枡したす。 await serve(handler, { port: 3000 }); Bun:  Bun.serve  ãƒ¡ã‚œãƒƒãƒ‰ã‚’䜿甚し、蚭定オブゞェクトを枡したす。 const server = Bun.serve({ ... }); 3. リク゚ストハンドラヌ:   Deno: 独立した関数ずしお定矩したす。 const handler = (req: Request): Response => { ... }; Bun: 蚭定オブゞェクト内の  fetch  ãƒ¡ã‚œãƒƒãƒ‰ãšã—お定矩したす。 fetch(req) { ... } 比范ポむント 䞊蚘の比范結果では、各ランタむムの HTTP サヌバヌ実装の違いがありたした。 以䞋に、䞻芁な比范ポむントをたずめたした。 1. TypeScript サポヌト : Node.js: 远加のツヌル (ts-node) ずタむプ定矩 (@types/node) が必芁。 Deno: ネむティブサポヌト。 Bun: ネむティブサポヌト。 2. セキュリティモデル : Node.js: デフォルトですべおのシステムリ゜ヌスにアクセス可胜。 Deno: 明瀺的な暩限付䞎が必芁 --allow-net フラグ。 Bun: Node.js 互換のモデルを採甚デフォルトでアクセス可胜。 3. API蚭蚈 : Node.js: 暙準的な http モゞュヌルを䜿甚。 Deno: モダンな Web 暙準に基づいた API。 Bun: シンプルなオブゞェクトベヌスの API。 4. モゞュヌルシステム : Node.js: ES Modules (import 構文) を䜿甚。 Deno: ES Modules ず URL ベヌスのむンポヌトを䜿甚。 Bun: 組み蟌みの Bun オブゞェクトを䜿甚。 5. 実行の簡単さ : Node.js: TypeScript を盎接実行するには远加のセットアップが必芁。 Deno: 远加のセットアップなしで TypeScript を盎接実行可胜。 Bun: 远加のセットアップなしで TypeScript を盎接実行可胜。 結論 結論ずしお、Node.js、Deno、Bunの3぀のランタむムは、それぞれ独自の匷みを持ち、JavaScript゚コシステムの倚様化ず進化に倧きく貢献しおいたす。 たた、これらのランタむムは急速に進化を続けおいるため、定期的に最新の動向をチェックし、必芁に応じお遞択を芋盎すこずをお勧めしたす。 本ブログが、読者の皆様のプロゞェクト遞択や技術的な意思決定の䞀助ずなれば幞いです。 より詳现な情報や具䜓的な䜿甚䟋に぀いおは、各ランタむムの公匏ドキュメントを参照するこずをお勧めしたす。 明日は、Tsan0409さんの蚘事です。お楜しみに。
この蚘事は、 ニフティグルヌプ Advent Calendar 2024 10日目の蚘事です。 CLIツヌルを瀟内にプラむベヌトtapリポゞトリを䜜成し、瀟内に配垃したした。 意倖ず蚘事がなかったのでその方法をご玹介したす。 アプリケヌションのリリヌスに䜿っおいるのはGoReleaserです。 きっかけ ニフティ株匏䌚瀟では珟圚Oneloginを䜿っおいたす。 AWSのIAM RoleにAssumeRoleする際は以䞋のOneloginが提䟛しおいるツヌルを䜿っおいる瀟員がほずんどです。 https://github.com/onelogin/onelogin-python-aws-assume-role このツヌルはjava版もあるのですが、どちらにせよランタむムのむンストヌルが必芁です。 たた比范的頻繁に曎新されおいるわけではないため、バヌゞョンによっおは䟝存ラむブラリの問題でセットアップが倱敗するなどの問題がありたした。 そこで、これをGoで䜜り盎すこずでシングルバむナリか぀セットアップ䞍芁にし぀぀、brewで配垃するこずでMacやWSL環境ぞの導入をより簡単にしようず決めたした。 サヌドパヌティ補の他のツヌルを䜿うずいう手段もありたしたが、私自身がむンフラ管理者ではない(党瀟向けの遞定暩がない)こずや、珟圚䜿っおいるツヌルからの移行モチベヌションを䞊げるため蚭定ファむルを流甚するこずが重芁だったこず、むンナヌ゜ヌス化するこずでより柔軟に開発者自身が必芁な機胜を远加しおいけるこずを重芖し、自䜜するこずに優䜍性があるず刀断したした。 Tapリポゞトリの䜜成 バむナリを配垃するためのtapリポゞトリを䜜成したす。 このリポゞトリの名前は homebrew-<repo> の圢匏である必芁がありたす。 https://docs.brew.sh/Taps#repository-naming-conventions-and-assumptions プラむベヌトなtapリポゞトリを䜜成する堎合、GitHubのトヌクンを䜿っおダりンロヌドURLを䜜る必芁がありたす。 以䞋のGistが非垞に参考になるため、これを䜿いたす。 https://gist.github.com/ZPascal/b21c652b811872b3f56db9d54d61d6c6 GitHubPrivateRepositoryDownloadStrategy ずいうクラスがダりンロヌド戊略ずなりたす。 指瀺通り、tapリポゞトリのlib/配䞋に配眮したす。 アプリケヌションの䜜成 今回はHomebrewで配垃する郚分がメむンなので、ここではGoReleaserの蚭定に぀いお玹介したす。 GoReleaserは簡単に耇数のOSやCPUアヌキテクチャ向けにBuildしたり、パブリッシュするこずができるツヌルです。 https://github.com/goreleaser/goreleaser このツヌルを䜿っおGitHub Actionsでリリヌスしおいたす。 アプリケヌションリポゞトリからtapリポゞトリにpushしおPRを䜜成する必芁があるため、PrivateAccessTokenが必芁になりたす。 ダりンロヌド戊略ずしお先ほど䜜成した GitHubPrivateRepositoryDownloadStrategy を䜿うよう指定したす。 .goreleaser.yaml version: 2 before: hooks: - go mod tidy - go generate ./... builds: - main: ./cmd/ binary: onelogin env: - CGO_ENABLED=0 goos: - linux - windows - darwin archives: - format: tar.gz name_template: >- {{ .ProjectName }}_ {{- title .Os }}_ {{- if eq .Arch "amd64" }}x86_64 {{- else if eq .Arch "386" }}i386 {{- else }}{{ .Arch }}{{ end }} {{- if .Arm }}v{{ .Arm }}{{ end }} format_overrides: - goos: windows format: zip changelog: sort: asc filters: exclude: - "^docs:" - "^test:" brews: - name: onelogin download_strategy: GitHubPrivateRepositoryReleaseDownloadStrategy custom_require: lib/private_strategy repository: owner: niftycorporation name: homebrew-tap branch: "{{ .ProjectName }}" token: "{{ .Env.PRIVATE_GITHUB_TOKEN }}" pull_request: enabled: true draft: false base: branch: master workflow name: Upload Release Asset on: push: tags: - 'v*' permissions: contents: write jobs: build: name: Upload Release Asset runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Go uses: actions/setup-go@v5 with: go-version-file: go.mod cache: true - uses: goreleaser/goreleaser-action@v6 with: distribution: goreleaser version: "~> v2" args: release --clean env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} PRIVATE_GITHUB_TOKEN: ${{ secrets.PRIVATE_GITHUB_TOKEN }} このWorkflowが実行されるずreleasesが䜜成され、tapリポゞトリにPRが䜜成されたす。 䞀郚倉曎しおいたすが、以䞋のようなファむルが生成されたす。 GoReleaserを䜿わなくおもこのようなファむルがあれば配垃するこず自䜓は可胜です。 onelogin.rb # typed: false # frozen_string_literal: true # This file was generated by GoReleaser. DO NOT EDIT. require_relative "lib/private_strategy" class Onelogin < Formula desc "" homepage "" version "1.0.2" on_macos do on_intel do url "https://github.com/niftycorporation/onelogin-go-aws-assume-role/releases/download/v1.0.2/onelogin-go-aws-assume-role_Darwin_x86_64.tar.gz", using: GitHubPrivateRepositoryReleaseDownloadStrategy sha256 "hash" def install bin.install "onelogin" end end on_arm do url "https://github.com/niftycorporation/onelogin-go-aws-assume-role/releases/download/v1.0.2/onelogin-go-aws-assume-role_Darwin_arm64.tar.gz", using: GitHubPrivateRepositoryReleaseDownloadStrategy sha256 "hash" def install bin.install "onelogin" end end end on_linux do on_intel do if Hardware::CPU.is_64_bit? url "https://github.com/niftycorporation/onelogin-go-aws-assume-role/releases/download/v1.0.2/onelogin-go-aws-assume-role_Linux_x86_64.tar.gz", using: GitHubPrivateRepositoryReleaseDownloadStrategy sha256 "hash" def install bin.install "onelogin" end end end on_arm do if Hardware::CPU.is_64_bit? url "https://github.com/niftycorporation/onelogin-go-aws-assume-role/releases/download/v1.0.2/onelogin-go-aws-assume-role_Linux_arm64.tar.gz", using: GitHubPrivateRepositoryReleaseDownloadStrategy sha256 "hash" def install bin.install "onelogin" end end end end end brew installする たずロヌカルからプラむベヌトリポゞトリにアクセスするためにPrivateAccessTokenを䜜成し、 HOMEBREW_GITHUB_API_TOKEN ずいう環境倉数に指定したす。 tapリポゞトリを指定し、むンストヌルしたす。 このずき、リポゞトリ名の homebrew- 郚分は省略するこずができたす。 brew tap niftycorporation/tap brew install niftycorporation/tap/onelogin Brewfileには以䞋のように蚘茉したす。 tap "niftycorporation/tap" brew "niftycorporation/tap/onelogin" これでプラむベヌトのtapリポゞトリでバむナリを配垃するこずができたした。 たずめ ここたでプラむベヌトのtapリポゞトリを䜜成し、配垃する方法を玹介しおきたした。 䌁業内で独自の゜フトりェアを配垃したいこずはそれなりに倚いんじゃないかず思っおいたす。 特に以䞋はかなりハマりポむントでした。 tapリポゞトリの呜名芏則 PATを䜿ったダりンロヌド戊略の䜜成 PATを䜿ったダりンロヌド戊略の指定 今ハマっおいる方や今埌やろうず思っおいる方はぜひこれらに気を぀けおいただければず思いたす。 ここからはタむトルに関係のない今埌の展望に぀いおですが、このリポゞトリは珟圚むンナヌ゜ヌスずしお瀟内公開しおいお利甚者も比范的倚いプロゞェクトになっおいるず考えおいたす。 しかしコントリビュヌタがなかなか増えず、敷居の高さや関心を匕けおいないこずが問題かず思っおいたす。 ツヌル自䜓メむン機胜はほが完成しおいたすが、爆速で䜜ったためリファクタリングや凊理の効率化、ドキュメントの敎備などやりたい事自䜓はただただある状況です。 たた、普段䜿わない蚀語や領域に觊れるなど゚ンゞニアずしおの成長も望めるため、コントリビュヌタを増やしむンナヌ゜ヌスやOSSに興味を持っおもらえるよう掻動しおいく予定です。 tapリポゞトリに぀いおも珟圚配垃されおいるのがこのツヌルのみずいうこずもあり寂しいので、こちらも敷居を䞋げより簡単に远加できるようになればいいなず想像しおいたす。 最埌に、この蚘事がどなたかのお圹に立おば幞いです。 明日は、@hayabusa01 さんの蚘事です。 お楜しみに
この蚘事は、 ニフティグルヌプ Advent Calendar 2024 9日目の蚘事です。 こんにちは。ニフティ株匏䌚瀟の statiolake です。 私は生粋の Neovimmer なのですが、これはなぜかずいうず自分の開発環境を自分奜みにカスタマむズするこずが倧奜きだからです。 耇雑で芚えおいられない凊理を自動化しお隠蔜し、シンプルで明快な操䜜で実行できるようにする。゚ンゞニアリングの粋ず蚀っおもよいでしょう。この営みを最も高速にむテレヌトできるこずこそ、自分の開発環境を敎えるこずなのです。 いきなり脱線しお恐瞮なのですが、先日開催された VimConf 2024 のキヌノヌトで、Neovim プラグむン開発者でストリヌマヌでもある TJ DeVries 氏もそのような講挔をされおいたした。 こちら、VimConf ながら Vim 固有の話はほがありたせんので、どなたでも楜しんでいただけるず思いたす。語り口の軜快さはさすがストリヌマヌずいったずころ。聞いおいお飜きるこずがありたせんでした。 ぀い最近 YouTube に動画が䞊がったようなので、よろしくお願いしたす。 䜕の話だ。 ええ、そういうこずもあっお、私はメタプログラミングも倧奜きです。 耇雑で曞いおいられないボむラヌプレヌトを隠蔜し、簡単で盎感的なコヌドで呌び出せるようになるず、なんかいいですよね。動的型付けで様々なものがオブゞェクトずしお扱える Python は、コヌドを簡単にかけるようにするこずにかけおは超䞀流ずいっお良いでしょう。 今回はそういったメタプログラミングで䜿えそうなテクニックの䞀぀ずしお、メ゜ッドのフリをするオブゞェクトを䜜る方法を孊んだので、共有したいず思いたす。 これを䜿ったら䜕ができるかは、たたいずれ別の蚘事にするかもしれたせん。 ※ なお、これは蚀語仕様などに立ち入った厳密な話ではないこずを先んじおお断りしおおきたす。そこたで詳しいわけではないです  関数のフリをするオブゞェクトの䜜り方 いきなりメ゜ッドに入る前に、普通の関数に぀いお考えおみたしょう。 def add(a, b): return a + b print(add(1, 2)) # => 3 実は、関数のように䜿えるオブゞェクトを䜜るのは結構簡単です。 確かに関数には add(1, 2) ずいう特別な文法を䞎えられおはいたす。しかし、それは実は add.__call__(1, 2) ず同じ意味になっおいたす。なので単に __call__ ずいうマゞックメ゜ッドを定矩しおあげれば呌び出し構文が䜿えるようになりたす。 class AddFunction: def __call__(self, a, b): return a + b add = AddFunction() print(add(1, 2)) # => 3 # ^^^ AddFunction クラスのむンスタンスであり、関数ではないが、呌び出せる 完璧です。 メ゜ッドはどうしお難しいのか これができるなら、別にメ゜ッドだっお同じような気がしたすよね。 class Calculator: def add(self, a, b): return a + b c = Calculator() print(c.add(1, 2)) # => 3 実際、これを先ほどのように __call__() を持ったオブゞェクトで眮き換えおも䞀芋、䜿えおいるように芋えたす。 class AddFunction: def __call__(self, a, b): return a + b class Calculator: # def add(self, a, b): # return a + b add = AddFunction() c = Calculator() print(c.add(1, 2)) # => 3 しかし、これには臎呜的な欠点がありたす。それは add() がむンスタンスに結び぀いおいないこずです。 メ゜ッドなのに self に結び぀いおいない 䟋えば電卓の M+ ボタンのように、Calculator クラス内に倀を保持するメ゜ッドを䜜りたいずしたす。しかし、今の圢だずそれが実装できたせん。 AddFunction の __call__ にある self はあくたでも AddFunction であっお Calculator ではないからです。 そもそも振る舞いが違う Python のメ゜ッドは少し䞍思議な性質を持っおいたす。 add() がメ゜ッドの堎合、 class Calculator: def add(self, a, b): return a + b c = Calculator() print(Calculator.add(c, 1, 2)) # => 3 print(c.add(1, 2)) # => 3 このように むンスタンス.メ゜ッド名(匕数...) で呌び出したずきは自動で self にオブゞェクトが入り、 クラス名.メ゜ッド名(むンスタンス, 匕数 ) で呌び出したずきには self にあたるものも自分で指定するこずができたす。 ずころが、今䜜ったオブゞェクトを䜿っおみるず  class Calculator: add = AddFunction() c = Calculator() print(Calculator.add(c, 1, 2)) # ^ TypeError: AddFunction.__call__() takes 3 positional arguments but 4 were given print(c.add(1, 2)) # => 3 なんず、3 ぀の匕数で呌び出すずころが䟋倖になっおしたいたした。確かに __call__() には 2 ぀の匕数しか入れられないので、゚ラヌになるのは理解できたす。 しかし、ならばなぜメ゜ッドぱラヌにならないのでしょうか 2 ぀の問題ずいうふうにお䌝えしたしたが、本質的には 1 ぀だけです。 結論から蚀えば、魔法がかかるのはメ゜ッド呌び出し時です。メ゜ッド add の本圓の姿は、 クラス名.メ゜ッド名 で呌び出されるのず同じ、 self を含めた 3 匕数の関数ず考えおください。 ぀たり、Python が むンスタンス.メ゜ッド名(匕数...) のずきだけ勝手に第䞀匕数にむンスタンスを結び぀けおくれおいる、よっお 2 匕数の関数のように䜿えおいる、ずいうこずになりたす。 普通のオブゞェクトがメ゜ッドのふりをするためには、この仕組みを自分で実装しなければいけたせん。そしおそれを可胜にする仕組みがデスクリプタです。 デスクリプタ ここから少し蟌み入った話になりたすが、Python にはデスクリプタずいうものが存圚したす。暙準にある @property デコレヌタの裏偎で䜿われおいる機胜でもありたす。 デスクリプタ は、メ゜ッドやフィヌルドを取埗しようずしたずきに割り蟌んで奜き勝手なオブゞェクトを返すこずができる機胜です。たあ他にもできるこずはあるんですが、ここでは割愛したす。 たずえば、以䞋の RandomValueDescriptor を䜿うず参照するたびに倀が倉わっおいる䞍思議なフィヌルドを䜜るこずができたす。 class RandomValueDescriptor: def __get__(self, instance, owner): return random.randint(1, 100) class Calculator: value = RandomValueDescriptor() c = Calculator() print(c.value) # => 34 (䟋) print(c.value) # => 84 (䟋) 普通のフィヌルドの堎合、 value に代入しおもいないのに倀が倉わっおいるずいうこずはありたせん。 しかしデスクリプタを䜿うず、 value にアクセスしたずきに毎回 __get__() 関数を通しおくれるようになりたす。そこではあらゆるコヌドが実行できるため、このように、ランダムな倀を返すこずもできるわけです。 そしお、 __get__ にはいく぀かの匕数がありたす。 ここで着目したいのは instance です。ここには むンスタンス.フィヌルド名 で呌ばれた時の むンスタンス が䞎えられおいたす。さらに、クラス名を経由しお呌ばれたずきは None が入っおいたす。 class InstanceDetectorDescriptor: def __get__(self, instance, owner): if instance is None: return "without instance" return "with instance" class Calculator: instance_detected = InstanceDetectorDescriptor() c = Calculator() print(Calculator.instance_detected) # => without instance print(c.instance_detected) # => with instance なるほど、 instance を芋おむンスタンスがあるかないかを取るこずができる。 もうおわかりですかね デスクリプタでメ゜ッドのフリをする ここたでの考察を螏たえお、以䞋のうち memory_add() メ゜ッドをオブゞェクトに眮き換えおみたしょう。 class Calculator: def __init__(self): self.memory = 0 def memory_add(self, delta): self.memory += delta c = Calculator() Calculator.memory_add(c, 1) # memory: 0 + 1 = 1 print(c.memory) # => 1 c.memory_add(1) # memory: 1 + 1 = 2 print(c.memory) # => 2 この䞭の、匕数の数がむンスタンスかどうかで倉わっおくる郚分が難しいのでした。しかし今の我々には、デスクリプタを䜿っお以䞋のこずが可胜です。 参照された瞬間を __get__() で割り蟌むこずができる __get__() の䞭でむンスタンスの有無がずれ、奜きなものを返せる であれば、こうでしょう。 むンスタンスが䞎えられなかったずきは、普通の関数を返す。 むンスタンスが䞎えられたずきは、それを第䞀匕数に玐づけ、䞀぀匕数が枛った関数を返す。 class MemoryAddMethodDescriptor: def __get__(self, instance, owner): def inner(self, delta): self.memory += delta if instance is None: # むンスタンスがない堎合 - クラス名.メ゜ッド名(むンスタンス, 匕数...) で呌び出された # 普通に関数をそのたた返す return inner # むンスタンスがある堎合 - むンスタンス.メ゜ッド名(匕数...) で呌び出された # 第䞀匕数にむンスタンスを䞎え、匕数を䞀぀枛らした関数を䜜っお返す # ここでは手っ取り早く lambda 匏を䜿っおいる return lambda delta: inner(instance, delta) class Calculator: def __init__(self): self.memory = 0 memory_add = MemoryAddMethodDescriptor() いけるはずです。さお、実行しおみるず  c = Calculator() Calculator.memory_add(c, 1) # memory: 0 + 1 = 1 print(c.memory) # => 1 c.memory_add(1) # memory: 1 + 1 = 2 print(c.memory) # => 2 成功ですしかも、きちんずむンスタンスにもアクセスできおいたすね。 ここでは __get__() が返すものをただの関数にしおいるので、あたり䟿利さが実感できないかもしれたせん。 しかし、ここで先皋の「関数のふりをするオブゞェクト」をさし挟むこずができおしたうずなれば、どうでしょうか あれも基本的には普通のクラスの普通のオブゞェクトですから、その䞭にメ゜ッドを远加するこずもできたすし、そうするず  いろいろなこずができおしたいたす。 長くなっおしたうので、今日はここたでですね。 終わりに 今回はメ゜ッドのふりをするオブゞェクトを䜜っおみたした。もちろん、これは単䜓であれば普通にメ゜ッドを定矩すれば良く、倧した意味を持ちたせん。しかし、オブゞェクトには奜き勝手に別のフィヌルドやメ゜ッドを増やすこずができ、自由床が高たりたす。 たずえば、私はこの機胜を単䜓テストのためのモッククラスに応甚しおみおいたす。 user = MockUserRepository() with user.get_all.patch([User(id=1, name="Alice")]): assert user.get_all() == [User(id=1, name="Alice")] この䟋では、 user.get_all の戻り倀を䞀時的に䞊曞きする機胜を提䟛しおいたす。 get_all はメ゜ッドのように呌び出せたすが、そこに patch() ずいうメ゜ッドがあるのは、今回の方法を䜿っお「メ゜ッドのふりをしたオブゞェクト」に差し替えおいるからです。具䜓的には、たた別の蚘事を曞くかもしれたせん。 そんなわけで、ちょっずした小道具でした。長らくお付き合いいただきありがずうございたす。みなさんも䜕かご存知の小道具があれば、ぜひ教えおくださいあず、TJ DeVries さんの講挔もぜひ芋おみおください。 明日は、dev-shimada さんの「瀟内Tapリポゞトリを䜜り自䜜ツヌルをHomebrewで配垃する」です。 お楜しみに
この蚘事は、 ニフティグルヌプ Advent Calendar 2024 7日目の蚘事です。 はじめに こんにちは、䌚員システムグルヌプで゚ンゞニアをしおいる山田です。 皆様、CloudFront Functionsは䜿っおいたすでしょうか。 CloudFrontで゚ッゞ凊理を行いたい堎合、 Lambda@Edge もしくは CloudFront Functions のいずれかを䜿甚するこずになりたす。CloudFront Functionsはランタむムの匷い制限を代償に、Lambda@Edge比で料金が玄1/6ず、安䟡に䜿甚するこずができたす。ニフティ瀟内でも静的サむトでのリダむレクト凊理などに掻甚しおいたす。 軜い凊理であるずはいえ、継続的な運甚を行うには型チェックやテストの恩恵を受けたいものです。 本蚘事はそのための環境をどう敎えるか、ずいう内容になりたす。 結論 結論から先に述べるず TypeScriptだけで良い堎合: tscでトランスパむルする テストもしたい堎合: バンドラヌでバンドル埌、 正芏衚珟でexportを陀去 する ずいう圢になりたす。 前提 前提ずしお、CloudFront FunctionsはサヌバサむドJavaScriptではあるものの、 Node.jsではない ランタむムで動䜜したす。このため、以䞋のような文法䞊の制玄がありたす。(JavaScript 2.0ランタむムの堎合) ECMAScript 5ベヌス const/let、async/awaitなど䞀郚のES6文法にも察応 ES Modules非察応 CommonJS向けのexport構文が゚ラヌずなる module.exports はmoduleがundefinedのため゚ラヌ 1ファむルのみデプロむ可胜 これらの制玄を満たすように䜜る必芁がありたす。 察応方法 型チェックのみで良い堎合 型チェックができればよい堎合は、TypeScriptの導入のみで良いです。 pnpm add -D typescript tsconfigの蚭定は以䞋のようにしたす。 { "compilerOptions": { "target": "es5", ... "baseUrl": "./src", "outDir": "./dist" }, "include": ["**/*.ts"], "exclude": ["node_modules", "dist"] } targetはES5にしおおきたす。ES6文法の倚くはCloudFront Functionsでも䜿甚可胜ですが、䞀郚非察応の文法を䜿甚しおも気づかないため、ES5にしおおくのが無難でしょう。 次にCloudFront Functions甚の型定矩を甚意したす。npmパッケヌゞずしお 公開されおいるもの があるため、これを䜿いたす。手元の環境では型情報をうたく参照できなかったため、内容をコピヌしお利甚しおいたす。 declare namespace AWSCloudFrontFunction { interface Event { version: '1.0'; context: Context; viewer: Viewer; request: Request; response: Response; } interface Context { distributionDomainName: string; distributionId: string; eventType: 'viewer-request' | 'viewer-response'; requestId: string; } interface Viewer { ip: string; } interface Request { method: string; uri: string; querystring: ValueObject; headers: ValueObject; cookies: ValueObject; } interface Response { statusCode: number; statusDescription?: string; headers?: ValueObject; cookies?: ResponseCookie; } interface ValueObject { [name: string]: { value: string; multiValue?: Array<{ value: string; }>; }; } interface ResponseCookie { [name: string]: { value: string; attributes: string; multiValue?: Array<{ value: string; attributes: string; }>; }; } } CloudFront Functionsの゜ヌスには䞊蚘の型を指定したす。 function handler( event: CloudFrontFunction.Event ): AWSCloudFrontFunction.Request | AWSCloudFrontFunction.Response { ... } あずはtscでコンパむルすればJavaScriptファむルが埗られたす。型チェックのみを行う堎合は別途コマンドを甚意しおおくずよいでしょう。 tsc テストもしたい堎合 テストも行いたい堎合、テスト察象関数をexportする必芁が出おきたす。たたファむルを分割したくなるこずもあるでしょう。このため、基本的にバンドラを䜿うこずになりたす。 しかしながら、バンドラの察応するいずれの出力圢匏でも問題を抱えおいたす。 ESM圢匏: handlerのexportが必須、 export ~ が文法゚ラヌ CJS圢匏: handlerのexportが必須、 module.exports = ~ がmodule倉数の未定矩により゚ラヌ IIFE圢匏: 関数定矩が倧きく倉わる ESM、CJS圢匏ではexportされおいない関数は䞍芁ず刀断され、バンドル埌の結果に残らなくなりたす。䞀方でexportするず出力結果にexportの文法が残るため、゚ラヌを匕き起こしおしたいたす。これらは esbuildのissue でも議論されおいたすが、いずれもHackyな回避策ずなっおいたす。 そこで、 ESM圢匏で出力したものからexportを陀去する ずいうアプロヌチを行いたす。 バンドラずしお今回はtsupを䜿甚したす。 pnpm add -D tsup 以䞋のように蚭定を行いたす。 import { defineConfig } from 'tsup'; export default defineConfig({ entry: [ // 出力したいhandlerがあるファむル矀 ], format: 'esm', platform: 'node', splitting: false, sourcemap: false, minify: false, clean: true, }); entryは耇数指定できるため、耇数の関数ファむルを䞀括しお生成するこずが可胜です。 たたビルド埌のファむルからexportを取り陀くスクリプトを甚意しおおきたす。 (コヌドによっおは正芏衚珟を調敎する必芁があるかもしれたせん) /* ビルド埌のファむルを加工するスクリプト usage: node scripts/postbuild.js {build_dir} CloudFront Functionsはexportを解釈できないため、ビルド埌のファむルからexportを削陀する */ import * as fs from 'node:fs'; import * as path from 'node:path'; // export文を刀別する正芏衚珟 const regex = /export\s*{[^}]*};?/gs; const target = process.argv[2]; const targetPath = path.resolve(target); if (!fs.statSync(targetPath).isDirectory()) { console.error('Target is not a directory'); process.exit(1); } const files = fs.readdirSync(targetPath); for (const file of files) { const filePath = path.join(targetPath, file); const stats = fs.statSync(filePath); if (stats.isDirectory()) { continue; } const ext = path.extname(filePath); if (ext !== '.js') { continue; } console.log('Removing export statement from', filePath); const fileContents = fs.readFileSync(filePath, { encoding: 'utf-8' }); const newContents = fileContents.replace(regex, ''); fs.writeFileSync(filePath, newContents); } あずはビルド埌にこのスクリプトを実行するようにしおおけばOKです。 tsup && node postbuild.js ./dist たずめ CloudFront FunctionsをTypeScript・テストに察応した環境で曞くための方法に぀いお解説したした。 どうしおもハック感のある方法を取らざるを埗ないのですが、行っおいるこずはシンプルなので今のずころこれで運甚するこずができおいたす。テストにも察応できたこずで、リダむレクトルヌル倉曎時のデグレ防止にも圹立っおいたす。 CloudFront Functionsの䞭身が耇雑になっおきお、動䜜の担保に䞍安がある方は詊しおみおはいかがでしょうか。 次回はnunaさんの蚘事です。お楜しみに。
この蚘事は、 ニフティグルヌプ Advent Calendar 2024  6日目の蚘事です。 はじめに こんにちは。ニフティ株匏䌚瀟の䞊朚です。 皆さんは、タスクの割り圓おや順番決めに頭を悩たせたこずはありたせんか 私はこれたで、オンラむンのあみだくじやルヌレットツヌルを利甚しおいたしたが、あみだくじの結果を目で远ったり、䜕床もルヌレットを回したりず、意倖ず手間がかかっおいたした。 「もっず簡単に、䞀発で機械的にタスクを割り圓おおくれるツヌルが欲しい」ずいう思いから、SlackのワヌクフロヌずZapierを䜿甚しお、タスクを簡単に割り圓おるツヌルを䜜成したした。 今回は、その方法に぀いおご玹介いたしたす。 Slackのワヌクフロヌを䜜成する Slackでワヌクフロヌを新芏䜜成したす。 「Slack内のリンクから」を遞択しおください。 ステップを远加したす。 「フォヌム」を遞択しおください。 フォヌムの内容を蚭定したす。 質問1でタスク名を入力するよう蚭定したす。 質問2で人の名前を入力するよう蚭定したす。 質問1、質問2で入力された内容を、slackにメッセヌゞずしお送信できるよう蚭定したす。 「メッセヌゞ」を遞択しおください。 「チャンネルぞメッセヌゞを送信する」を遞択しおください。 今回は「ワヌクフロヌが䜿甚されたチャンネル」に、以䞋の内容のメッセヌゞが送信されるよう蚭定したす。 これでワヌクフロヌの䜜成は完了です Zapierを蚭定する たずはトリガヌの蚭定をしたす。 Appは「Slack」、Trigger eventは「New Mention」を遞択したす。 Slackに「タスク簡単割り圓おワヌクフロヌを起動したした。」ずいう文章が投皿されたらZapierが起動するよう蚭定したいので、Highlight Wordには「タスク簡単割り圓おワヌクフロヌを起動したした。」を蚭定したす。 Trigger for Bot Messages?は、Botによる投皿もトリガヌの察象に含めるかを確認しおいたすので、今回は「True」を遞択しおください。 タスクをランダムに割り圓おる凊理を曞いおいきたす。 Appは「Code by Zapier」、Action eventは「Run Python」を遞択したす。 蚀語はPythonのほかにJavascriptを遞択するこずもできたす。 Input Dataの右偎の入力ボックスにSlackで投皿された文章を蚭定し、巊偎の入力ボックスにキヌ名を入れたす。 以䞋画像ではキヌ名を「original_text」ずしたしたが、どんな名前を぀けおも良いです。 Codeの䞭で input_data['original_text'] ず曞くこずで、Input Dataで蚭定したデヌタを取り出すこずができたす。 def custom_shuffle(lst): # 簡易的な疑䌌乱数生成 seed = sum(ord(c) for c in ''.join(lst)) for i in range(len(lst) - 1, 0, -1): seed = (seed * 1103515245 + 12345) & 0x7fffffff j = seed % (i + 1) lst[i], lst[j] = lst[j], lst[i] return lst # ワヌクフロヌを䜿った人の名前ずタスクず人名を取り出す text = input_data['original_text'] lines = text.split('n') mention = lines[0] tasks = lines[4].split(',') people = lines[6].split(',') # タスクず人名をシャッフル tasks = custom_shuffle(tasks) people = custom_shuffle(people) # 結果を生成 result = "" for i in range(len(tasks)): person_index = i % len(people) # 人数を超えた堎合は最初から割り圓お盎す result += f"{tasks[i]}{people[person_index]}n" output = [{'result':result, 'mention':mention}] タスクを割り圓おた結果を、Slackに投皿したす。 Appは「Slack」、Trigger eventは「Send Channel Message」を遞択したす。 ChannelにSlack投皿するチャンネル名、Message textにSlack投皿するメッセヌゞを入力したす。 Codeの最埌に output = [{'result':result, 'mention':mention}] ず蚘茉しおおくこずで、タスクを割り圓おた結果ずワヌクフロヌを䜿った人の名前を取り出しお、メッセヌゞに含めるこずができたす。 これでZapierの蚭定は完了です 実際に動かしおみる ワヌクフロヌを実行し、タスク名ず名前をカンマ区切りで入力したす。 「送信する」を抌䞋するず、ワヌクフロヌを実行したチャンネルに、以䞋のメッセヌゞが投皿されたす。 さらに数秒埅぀ず、タスクを割り圓おた結果が「#bot_タスク割り圓お」チャンネルに投皿されたす おわりに 以前の蚘事「 ZapierでX投皿するAPIを呌び出しお結果をSlackに通知しおみた 」では、Zapierから Slackぞの連携を詊したしたが、今回は逆に Slackの投皿をトリガヌにしお Zapierを起動させる方法を初めお実践したした。 今埌も、SlackずZapierの連携を掻甚しお、業務効率化や情報共有の改善に圹立぀ツヌルを開発しおいきたいず思いたす。 明日は、 jimmysharp さんの「CloudFront FunctionsでもTypeScript&テストしたい」です。 お楜しみに
この蚘事は、 ニフティグルヌプ Advent Calendar 2024  5日目の蚘事です。 はじめに ニフティでWEBサヌビスの開発・運甚を担圓しおいる枡邊です。 最近、運甚の手間をかけずにWEBサヌビスを立ち䞊げる方法はないかなず考えおいたずころ、AWS App Runner以䞋App Runnerに出䌚いたした。 この蚘事では、App Runnerの特城や他のサヌビスずの違いに぀いお曞いおいきたす。 App Runnerずは App RunnerはAWSのサヌビスの1぀で、コンテナアプリケヌションを簡単にデプロむ・運甚できるプラットフォヌムです。 GitのコヌドやコンテナをAWSにアップロヌドするだけで環境が䜜れるので、むンフラ呚りを気にする必芁がありたせん。 ECSFargateをベヌスにしおいるので、負荷に応じお自動的にスケヌルするのが特城です。 たた、VPCやロヌドバランサヌの蚭定が䞍芁なので、ネットワヌクの知識がなくおも䜿えたす。 他のAWSサヌビスずの違い AWSには䌌たようなサヌビスがいく぀かありたすが、App Runnerは「ずにかく簡単に䜿える」こずを重芖しお䜜られおいたす。 䞻なサヌビスを比べおみたしょう。 サヌビス メリット デメリット Amazon EC2 • サヌバヌを自由に蚭定できる • OSやミドルりェアを自分で遞べる • どんな甚途でも䜿える • 管理が倧倉 • 予想以䞊に費甚がかかるこずも Amazon ECS •コンテナ運甚に䟿利 • Fargateなら運甚が楜 • 自動でスケヌルする • むンフラの知識が必芁 • 初期蚭定が面倒 Elastic Beanstalk • デプロむが簡単 • AWSの他サヌビスず連携しやすい • サヌバヌ管理䞍芁 • 自動でスケヌルする • AWSぞの䟝存が匷くなる • 初期蚭定が面倒 AWS App Runner • デプロむが簡単 • シンプルな蚭定項目 • 運甚の手間なし • GitやDockerからすぐ䜿える • 自動でスケヌルする • 现かい蚭定ができない • AWSぞの䟝存が匷くなる 蚭定項目 蚭定する項目が少なくお、画面の流れに沿っお進めるだけで䜿えたす。 WAFも蚭定できるので、IP制限をかけたい瀟内向けのアプリも䜜りやすいです。 コスト フロントずバック゚ンドを分けたアプリを䟋に、コストを蚈算しおみたした。 トラフィック 月間50䞇リク゚スト 1リク゚ストあたり平均200ミリ秒 リ゜ヌス芁件 フロント゚ンド1 vCPU、2GBメモリ バック゚ンド2 vCPU、4GBメモリ サヌビス タスク/むンスタンス ALB NAT Gateway デヌタ転送 合蚈 ECS Fargate $138.66 $20.20 $32.40 $57.36 $248.62 EC2 $46.80 $20.20 $32.40 $57.36 $156.76 App Runner $195.75 䞍芁 䞍芁 䞍芁 $195.75 蚈算匏 ECSfargate フロント゚ンド vCPU コスト $0.05056 × 1 vCPU × 750時間 = $37.92 メモリ コスト $0.00553 × 2GB × 750時間 = $8.30 合蚈$37.92 + $8.30 = $46.22 バック゚ンド vCPU コスト $0.05056 × 2 vCPU × 750時間 = $75.84 メモリ コスト $0.00553 × 4GB × 750時間 = $16.60 合蚈$75.84 + $16.60 = $92.44 EC2 フロント゚ンド $0.0208 × 750時間 = $15.60 バック゚ンド $0.0416 × 750時間 = $31.20 デヌタ転送の仮定条件 ALB経由クラむアント → Fargate 平均リク゚ストサむズを1MBず仮定 デヌタ転送量500,000リク゚スト × 1MB = 500GB NAT Gateway経由Fargate → むンタヌネット デヌタ転送量10GB/月 デヌタ転送コスト ALB 経由 (500GB - 1GB無料枠) × $0.114 = $56.91 NAT Gateway 経由 10GB × $0.045 = $0.45 合蚈デヌタ転送コスト $56.91 + $0.45 = $57.36 コスト面ではEC2が最も安䟡ですが、運甚の手間を考えるずApp Runnerも悪くないかなず思いたす。 App Runnerの裏偎はECSFargateのため、同じ環境でありながら安くなるこずがわかりたす。 さらに、App Runnerは実行時間ベヌスの課金䜓系を採甚しおいるため、コストの予枬が容易ずいう利点もありたす。 App Runnerの制限ず考慮すべきポむント ARM64をサポヌトしおいない 蚘事執筆時点ではARM64のコンテナむメヌゞには察応しおいないため、x86_64アヌキテクチャのむメヌゞを䜿甚する必芁がありたす。 ARM64は、コストずパフォヌマンスの䞡面でメリットがあるため、今埌の察応に期埅です。 カスタマむズ性の制限 ずにかく簡単に䜿えるこずを重芖しおいるので、现かい蚭定はできたせん。 特にVPC接続やログ蚭定などの高床な構成が必芁な堎合、䜜業が耇雑になるこずがありたす。 オヌトスケヌリングの指暙が限定的 同時実行数でしかスケヌルできず、CPUやメモリの䜿甚率では制埡できたせん。 そのため、特定のアプリケヌションではスケヌリング芁件ずの䞍䞀臎が生じ、効率的な運甚が難しくなる可胜性がありたす。 サむドカヌコンテナ非察応 サむドカヌコンテナが䜿えないので、ログ収集やモニタリングをする時に工倫が必芁です。 たずめ コンテナを䜿うのが圓たり前になっおきた今、シンプルなWEBサヌビスを䜜るならApp Runnerはかなり䜿えるず思いたす。 実際に詊しおみたら、玄20分ほどでアプリケヌションがAWS䞊で動䜜できるようになりたした。プロトタむプや瀟内ツヌルを䜜るのにぎったりですね。 むンフラの心配をせずに開発に集䞭できるのが、個人的にすごく気に入っおいたす。 ただ、现かい蚭定やスケヌリングが必芁な堎合は、ECSやEC2も怜蚎した方がいいかもしれたせん。 参考 AWS App Runner AWS Fargate Amazon EC2 AWS Elastic Beanstalk
はじめに ニフティグルヌプ Advent Calendar 2024 2日目の蚘事です  はじめたしお 私はサポシスず呌ばれるチヌムに所属しおおり、普段カスタマヌサポヌトセンタヌ(以降CS)向けのアプリケヌションの開発ず運甚を担圓しおいたす。 CS向けのアプリケヌションはパッケヌゞアプリケヌションを利甚するだけでなく、完党内補のアプリケヌションの䜜成なども行っおいたす。サポシスでは、これらの内補ツヌルのデプロむは Terraform ず AWS SAM を䜿甚しおいたす。 本蚘事では、それらのツヌルを遞択した理由ず、実際の䜿っおみた開発メンバヌの声を玹介しおいきたいず思いたす。 IaCの遞択肢 デプロむ先はAWSずしたす。AWSで利甚可胜なIaCの䞀芧は以䞋の通りです。 Cloudformation AWS CDK AWS SAM AWS Chalice Serverless Frameworks Terraform Pulumi 各ツヌルの説明に぀いおは、ここでは割愛したす。 珟圚サポシスでは、ECSなどを含むアプリケヌションは Terraform、Lambdaのみで完結するツヌルはAWS SAMを䜿甚しおいたす。 ツヌルの遞定理由 それぞれのツヌルを遞んだ理由に぀いお、各ツヌルの長所ず短所を亀えながら説明しおいきたす。 Terraform 冪等性が担保される Terraformは宣蚀型のIaCずしお蚭蚈されおおり、状態をtfstateファむルを甚いお管理したす。デプロむにはAWSのAPIを利甚しおおり、APIの呌び出し結果を元に、tfstateファむルを曎新するこずで冪等性を担保しおいたす。たた、デプロむ時にはtfstateファむルずAWS䞊のリ゜ヌスを比范し、差分がある堎合のみデプロむを実行するため、無駄なデプロむを防ぐこずができたす。 リ゜ヌスのAPIコヌル順序はTerraform偎で自動的に制埡されるため、コヌド内での蚘述順序を気にする必芁はありたせん。 瀟内・瀟倖ずもにナレッゞが豊富 Terraformはニフティ内で5幎以䞊前から利甚されおおり、倚くの瀟員が䜿い慣れおいるツヌルです。そのため、トラブルが発生した際も瀟内の経隓者に盞談するこずで解決できるこずが倚く、瀟内ドメむンに沿ったベストプラクティスなども成熟し぀぀ありたす。 たた、瀟倖でも広く利甚されおいるため、むンタヌネット䞊の情報も豊富で、トラブルシュヌティングが容易です。 モゞュヌル分割機胜が䟿利 モゞュヌルを再利甚可胜な単䜍に分割でき、環境䟝存の蚭定を倖偎に分離するこずで、本番環境ず開発環境のデプロむを効率的に管理できたす。 サヌバヌレスアプリの開発には向いおいない Terraformはサヌバヌレスアプリケヌションの管理が埗意ではありたせん。特にLambdaに関しおは、1぀の関数に察しお倚くのプロパティを蚭定する必芁があり、たた、デプロむに必芁なzipファむルのビルドプロセスも耇雑になりがちです。そのため、私たちのチヌムではこれらの課題に察凊するためにAWS SAMを採甚しおいたす。 コラム動画玹介 Terraformのメリットに぀いお、もっず詳しく知りたい方は、うちのメンバヌが分かりやすく解説しおいるTech talkの動画もチェックしおみおください AWS SAM 各皮パッケヌゞの管理が容易 AWS SAM はデプロむ前にビルドプロセスが実行したす。その際に必芁なパッケヌゞのむンストヌルずデプロむ甚のzipファむルの䜜成が自動的に行われたす。 こちらのbuildはオプションでコンテナ䞊でも行うこずができるため、build環境に䟝存しない䜜りにするこずができたす。 開発機胜が豊富 ロヌカル環境での実行・テストが可胜で、コンテナベヌスの動䜜により環境䟝存性を排陀できたす。たた、syncずいうリモヌトのAWS䞊ずロヌカルのコヌドを動悞する機胜も搭茉されおおり、開発効率を向䞊させるこずができたす。 チヌム間での管理が容易 CloudFormationを利甚しお管理されおいるため、tfstateファむルずいった䟝存関係管理ファむルをS3にアップロヌドする必芁がありたせん。たた、リ゜ヌスの削陀もCLIだけでなく、AWSコン゜ヌルから䞀括で行うこずができたす。 倧芏暡アプリケヌションは䞍向き CloudFormationをベヌスずしおいるため、モゞュヌル化しお分離するこずがほが䞍可胜ずなっおいたす。たた、YAML圢匏で曞かれおいるため、コヌドが冗長になっおしたい、可読性が䜎䞋するこずもAWS SAMの課題です。 実際に運甚しおみお チヌムメンバヌからの感想を聞いおみたした。 コン゜ヌルでの䜜業手順の䜜成が䞍芁になったのは嬉しい デプロむ時はIaCを通さなければいけないので、党員が倉曎履歎を远えるようになった Git(GitHub)で管理できるようになったので、バヌゞョン管理ができるようになった デプロむ時は環境差分のみに集䞭すればよくなったので、非垞にリリヌス時のミスが枛った AWS SAMに関しおは、実行たで手元の゚ディタで党お完結するのは開発䜓隓ずしおいい デプロむが遅いので、埅たなければいけないのは䞍䟿(lambdaのコピペは盎ぐにすんだので) 管理が楜になるず回りから聞いおいたけど、実際は思っおいたより楜ではなかった IaCが読めるようになるたでの孊習コストが高い コヌドで党お管理できるが、グラフィカルに䟝存関係を芋るこずができないのは残念 IaCの導入によっお管理効率や倉曎履歎の远跡が向䞊した䞀方で、孊習コストやデプロむ時間などの運甚面での課題も芋えおきたした。 たずめ 本蚘事では、ニフティのサポシスチヌムにおけるIaCツヌルの遞択ず運甚に぀いお玹介したした。Terraformは冪等性の担保や豊富なナレッゞ、モゞュヌル分割機胜など、倧芏暡なむンフラ管理に適しおいる䞀方、AWS SAMはサヌバヌレスアプリケヌションの開発に特化した機胜を提䟛しおいたす。 実際の運甚では、倉曎履歎の远跡やバヌゞョン管理、環境差分の管理が容易になるなどのメリットが確認できたした。䞀方で、孊習コストやデプロむ時間、可芖化の課題なども浮き圫りになりたした。 これらのツヌルを目的に応じお䜿い分けるこずで、より効率的なむンフラ管理が可胜になっおいたす。今埌も開発者の声に耳を傟けながら、より良い開発環境の敎備を進めおいきたいず思いたす。
初日から遅刻しおすみたせん。12/1が日曜始たりであるこずを完党に忘れおいたした。 ニフティでスクラム゚バンゞェリストをしおいる西野です。業務では2チヌムのスクラムマスタヌをしおいたす。 最近、シチュ゚ヌショナルリヌダヌシップの本を読んで実践しおみたので、今回はスクラムにおけるリヌダヌシップに぀いおお話ししたいず思いたす。 スクラムチヌムにリヌダヌは䞍芁 「スクラムマスタヌはチヌムリヌダヌではない」「スクラムチヌムには䞊䞋関係がないので、いわゆるリヌダヌはいない」ずいう話を聞いたこずはないでしょうか。 スクラムガむドには「スクラムマスタヌは真のリヌダヌである」ずも曞かれおあり、混乱するかもしれたせんが、これに぀いおは埌述したす リヌダヌっおなんだろう リヌダヌず聞いおどんなむメヌゞが浮かびたすか 瀟䌚人ならチヌムリヌダヌや䞊叞、孊生の頃なら郚掻の郚長や生埒䌚長が身近なリヌダヌ像でしょうか。最近では新しい総理倧臣のリヌダヌシップにも泚目が集たっおいたす。 いずれにしろ、リヌダヌずはチヌムをゎヌルに導く力があり、組織の意思決定を行い、人が埌ろを぀いおいきたくなるようなスタヌ性、カリスマ性を持っおいるようなむメヌゞがありたす。 そんな理想的なリヌダヌに自分がなれず蚀われたら困りたすが、身近にいおくれたらどれほど頌もしいでしょうか。スクラムでは、そのようなリヌダヌを「䞍芁」ずしおいるわけではありたせん。 リヌダヌず䌌たような肩曞きずしお「ボス」もありたす。ボスずいう蚀葉には「ふんぞりかえっお怅子に座り、暩嚁的であり、指瀺はするが盎接手は動かさない人」のようなむメヌゞがありたす。 この「ボス」ず䞀緒に働くのはたずえボスに心酔しおいるずしおも楜しいよりは苊しそうなむメヌゞがありたす。 䞀方で、もし「頌りになるリヌダヌ」ず䞀緒に働けたら、より安心しお、幞せに働けそうなむメヌゞがわくのではないでしょうか。 スクラムチヌムにボスは䞍芁ですが、リヌダヌは必芁です。 さらに、スクラムチヌムのリヌダヌはひずりだけではありたせん。リヌダヌシップが発揮できる人がいればいるほど、チヌムのアゞリティが増しおいくのです。 この「チヌムにリヌダヌがたくさんいる」ずはどんな状態でしょうか。 柔軟なリヌダヌシップスタむル 自分がスクラムにおけるリヌダヌシップに぀いお意識するようになったのは、 Regional Scrum Gathering Tokyo 2022 1日目基調講挔にあったAgile Program Managementずいうセッションがきっかけでした。 このセッションで「スクラムチヌムは党員がリヌダヌであり、リヌダヌずフォロワヌがシヌンによっお切り替わる」ずいう話を聞き、参加者同士でリヌダヌシップの解釈に぀いおかなり盛り䞊がった蚘憶がありたす。 この話を聞いた圓初は、党員がリヌダヌずいう状況がむメヌゞできたせんでした。党員が意思決定者ずいう状況では、進むものも進みたせん。「船頭倚くしお船山に䞊る」ずいう諺もあるくらい普遍的なアンチパタヌンです。 ここで倧事なのは、党員がリヌダヌずいう点よりも「 リヌダヌずフォロワヌがシヌンによっお切り替わる 」ずいう点です。 䟋えば、あるシヌンではiOSが埗意なAさんがリヌディングするが、別のシヌンではAndroidが埗意なBさんがリヌディングするずいう状況を指しおいたす。 この堎合、AさんもBさんもどちらもリヌダヌシップを発揮しおいたす。しかし、AさんもBさんも垞にリヌダヌではなく、お互いが埗意なシヌンごずにリヌダヌをサポヌトする偎フォロワヌにたわっおいたす。 技術領域以倖でも、説明が䞊手なCさんにチヌム倖ずの亀枉をお願いしたり、粟床が求められる仕事はゆっくりだが確実に仕事をこなしおくれるDさんを䞭心にお願いしたりするなど、成熟したチヌムではその人の特性や埗意分野に応じお自然ず堎をリヌディングする人が倉わっおいきたす。 シチュ゚ヌショナルリヌダヌシップずいう考え方 圓時この「リヌダヌずフォロワヌがシヌンによっお切り替わる」ずいう考え方に感銘をうけたのですが、先日同僚から「新1分間リヌダヌシップずいう本が良い」ず聞いお読んだずころ、この「柔軟なリヌダヌシップスタむル」に぀いおわかりやすく曞かれおいたので玹介したす。 人がどういう成長過皋にあるかにあわせお、発揮するリヌダヌシップを倉える 䟋えば特定の分野が未経隓の新入瀟員ず、経隓枈み10幎目の瀟員が同時にチヌムにアサむンされたずきに、業務に察しお同じ教え方をするでしょうか。 1幎目のメンバヌにはかかりきりで教えるこずになるでしょうし、10幎目のメンバヌには逆に「もっず効率的なやり方はないか」ず教えを乞うかもしれたせん。 このような単玔な䟋だずわかりやすいですが、珟実はもっず耇雑です。 察応者の分野ごずの熟緎床ずリヌダヌの接し方がかみあわないず、「わかっおいるのに现かく指瀺をしおくる」「ぜんぜんわからないのに䜕の指瀺もなく途方にくれる」ずいったチヌム内䞍和がうたれたす。 意識合わせアラむンメント察話をする その人の熟緎床の認識ずリヌダヌの接し方で䞍和を生たないために、リヌダヌは1on1の堎でこの認識を合わせたす。スクラムの堎合は、たずはスクラムマスタヌずチヌムメンバヌで1on1をするのが良いでしょう。 自分も月1の頻床でチヌムメンバヌず1on1をしおいるので、実際に以䞋に぀いお聞いおみたした。 成長段階の認識合わせ 「新1分間リヌダヌシップ」の本では、仕事における発達の過皋を以䞋のように定矩しおいたす。 D1:意欲満々な初心者 メンバヌの状態技胜が䜎く、意欲が高い 仕事のやりはじめ。なにもわからないが、指瀺にどんどん埓っお仕事を芚えるやる気に満ち溢れおいる。 リヌダヌの接し方现かく具䜓的に指瀺を出す「指瀺型」で接する。リヌダヌが自らやっおみせるシヌンもある。 D2:期埅が倖れた孊習者 メンバヌの状態技胜が䜎〜䞭で、意欲は䜎い 孊習が進んで技胜は身に぀いおくるが、さらに芋えおきた難しさや自分の技胜の远い぀かなさなどでやる気が䜎䞋しおいる リヌダヌの接し方「指瀺型」ず「支揎型」どちらも行う。指瀺の背景にある意図を説明し、メンバヌの意芋を聞いお意思決定に加わるよう促す。 D3:慎重になりがちな貢献者 メンバヌの状態技胜が䞭〜高で、意欲は䞍安定 できるこずが増えおきお、仕事に察する意欲が戻っおくる。しかし、ひずりで回せるほどの技胜はなく自信をもっお取り組めない。 リヌダヌの接し方「指瀺型」は少なく、「支揎型」が倚い。メンバヌずリヌダヌ共同で意思決定を行う。リヌダヌは聞き圹に回っおアむデアを匕き出す。 D4:自立した達成者 メンバヌの状態技胜が高く、意欲も高い この分野においおは䜕でも任せろずいう状態。自信もある。 リヌダヌの接し方意思決定も含めおその人に任せ、指瀺はしない。その人の貢献を評䟡し、成長を応揎する。 このように、孊習段階に応じおリヌダヌの接し方が倉わるずいうこずを説明した䞊で「自分がどの段階にいるか」をメンバヌに確認しおもらいたす。 本来はタスクごずに现かく認識合わせをしたほうがいいのですが、たずは「今自分がいるスクラムチヌムの仕事においおどのくらいか」ずいう粒床から始めたした。 たた、スクラムマスタヌの私から芋おどう芋えおいるかずいうこずも䌝えお盞互に認識合わせをしたした。 自分がゞョむンしおいる2぀のチヌムでやっおみたずころ、盞互の認識はほが䞀臎しおいたしたが、ズレる堎合は本人が思うより私の評䟡の方が高く感じおいるこずが倚かったです。 基本的にはメンバヌの意芋を重芖したすが、過床に䜎く評䟡しおいるようであれば、事実を亀えおもっずできおいるこずを䌝えるこずも行いたした。 もし1on1のコヌチ偎が思うよりメンバヌ自身の評䟡を高く眮いおいる堎合は、メンバヌの認識そのたたで目暙を立おおよいそうです。高い目暙に向けお頑匵ろうずするので、次第に本圓にその評䟡に远い぀くず本にありたした。 党員がリヌダヌに「なれる」チヌムをめざす 䞊蚘の認識合わせはただ1回やっただけなので、これによっお具䜓的にチヌムが倉わったずいうこずは珟段階では起きおいたせん。ただ、1on1の始たりのフェヌズで今埌も䜿っおいきたいず思っおいたす。 自分の立ち䜍眮を瀺すものずしおわかりやすいこずもありたすが、個人的には、たずはこのような考え方を通じお、可倉するリヌダヌシップのあり方をメンバヌに䌝えおいくこずが倧事だず考えおいるからです。 冒頭に「スクラムチヌムにリヌダヌは䞍芁」ず曞きたしたが、スクラムチヌムには、ボスや固定のリヌダヌは䞍芁です。シヌンに応じお誰でもリヌダヌの垜子を被れるようにしたす。 これは「スクラムマスタヌは真のリヌダヌである」ずいうスクラムガむドの蚀葉ずも矛盟はしたせん。私はこの蚀葉を、スクラムマスタヌは、チヌムや組織のあり方を良くできそうなトラむアンド゚ラヌを 誰よりも率先しお行う ずいう意味で捉えおいたす。 䟋えば、シチュ゚ヌショナルリヌダヌシップをスクラムマスタヌが率先しお実斜し、それを芋おチヌムメンバヌがリヌダヌシップを発揮しおくれるずしたら、それはスクラムマスタヌが真にチヌムをリヌディングしおいる状態ずいえるのではないでしょうか。 リヌダヌずは、その名の通り先頭に立っおものを匕っ匵る人です。ずっず䞀人でやっおいたら疲れおしたうし、フォロワヌも䞀人の背䞭を芋お孊べるこずは限られおしたいたす。 シヌンに応じお色々な人がリヌディングできれば、色々な人の背䞭を芋お孊びをもっず増やすこずができたす。たた、自分がリヌディングしおいるずきも、埌ろにはリヌダヌになれるくらい匷力なフォロワヌが぀いおいるずいう安心感もありたす。 スクラムチヌムは決しおリヌダヌが䞍圚なチヌムではありたせん。シヌンに応じお誰でもリヌダヌの垜子を被るこずができるチヌムなのです。 シチュ゚ヌショナルリヌダヌシップずいう考え方は、自埋的なチヌムを育むために良い足掛かりになるず思いたす。 スクラムにおけるリヌダヌシップのあり方を䌝えるために、1on1などのシヌンで、シチュ゚ヌショナルリヌダヌシップの説明ずお互いの「成長段階の認識合わせ」にぜひトラむしおみおください。
この蚘事は、 ニフティグルヌプ Advent Calendar 2024 3日目の蚘事です 2日続けおの投皿になりたす。 はじめに Azure も AWS ず同じく仮想ネットワヌクのサブネットを぀くるこずができたす。 今回は、い぀もどれくらいのCIDRで䜜成すればいいのかわからなくなるので、少し考察しおみたずきの蚘録をご玹介したす。 システム的な最小倀 サブネット サポヌトされる最小の IPv4 サブネットは /29、最倧は /2 です。 Azure Virtual Network に関する FAQ サブネット自䜓の制限ずしお、䞊蚘のルヌルがありたす。 AWSのサブネットは /28 たでなので、かなり现かく分割できたすね。 その他のサヌビス Azureには サブネットの委任 ずいう仕組みがありたす。 Azure 仮想ネットワヌクでのサブネットの委任ずは これは、特定のAzure PaaSサヌビスでサブネットを占有する仕組みであり、Azure Database for MySQL などをプラむベヌトなネットワヌク䞊に構築したいずきなどに䜿甚したす。 察しが良い方は気づいたかもしれたせんが、実はPaaSサヌビスごずに委任されるサブネットの倧きさに制限がかかっおいたす。 サヌビス名 最小 最倧 備考 参考 Azure App Service /28 /26(1぀のマルチテナントの最倧スケヌル数) MPSJ を利甚する堎合は /26 が最小 https://learn.microsoft.com/ja-jp/azure/app-service/overview-vnet-integration Azure Database for MySQL /29 䞍明 https://learn.microsoft.com/ja-jp/azure/mysql/flexible-server/concepts-networking-vnet システムに予玄されるIP サブネットを䜜成した時、サブネットに割り圓おたIPがすべお䜿えるわけではありたせん。先頭ず末尟のアドレスはそれぞれネットワヌクアドレスずブロヌドキャストアドレスずしお予玄されたす。たた、Azureは1぀のサブネットに぀き3぀のアドレスをシステム的に予玄したす。 そのため、最終的に利甚可胜なIPは、 サブネットのIPCIDRから5アドレス陀いたIPになりたす。 Azure Virtual Network に関する FAQ 運甚に沿った最小倀を考察 IP制限するずいうこずは、それだけスケヌリングの幅を狭めるこずずなりたす。たた、仮想ネットワヌクを分割しすぎるず管理するこずも倧倉です。そのためAzureでは VNetは倧きく、Subnetは小さく䜜るこずが掚奚されおいたす。 Azure Virtual Network に関する FAQ しかしながら、匊瀟のネットワヌク構成の制玄䞊、VNetは倧きく䜜成するこずができたせん。 では、どれくらいのCIDRが珟実的な蚭定倀なのでしょうか 1぀のVNetを占有するアプリケヌションの堎合 おそらく1぀のVNetを1぀のアプリケヌションで占有するこずになるず思いたす。 利甚するサヌビスにもよりたすが、最䜎でも /26 のVNetを甚意しお、4぀以䞊( /28 )に分割しお䜿いたいです。 より倧芏暡な堎合は、 /24 で払い出したうえで8぀以䞊( /27 )に分割しお䜿えるず安定しお運甚ができそうです。 1぀のVNetに耇数のアプリケヌションがあいのりする堎合 こちらはあいのりするアプリケヌションの数によりたす。 4぀ほどなら、最䜎でも /26 のVNetを甚意しお、4぀以䞊( /28 )に分割で足りるず思いたす。 それ以䞊は、4぀ほどなら、最䜎でも /25 のVNetを甚意しお、8぀以䞊( /28 )に分割で足りるず思いたす。 小さいアプリケヌションだず思うので、1぀のサブネットは /28 で十分賄えるず思いたす。 たずめ 本蚘事では、サブネットの蚭定をしたずきの考察を曞きたした。 IP制限されおいる環境ず通信したい堎合は適切にsubnetを䜜成しお管理しおきたいですね。
この蚘事は microCMSでこんなこずができたあなたのナヌスケヌスを倧募集 by microCMS Advent Calendar 2024 3日目の蚘事です。 はじめに こんにちは、ニフティ株匏䌚瀟の宮本です。 今回はmicroCMSのアドベントカレンダヌ参加蚘事なので、初めおNIFTY engineeringを閲芧する方も倚いず思いたす。 ニフティでもmicroCMSを利甚しお耇数のサむトを運甚をしおおり、せっかくなので今回のアドベントカレンダヌに参加させおいただきたした。 コンテンツの内容によっお通知先を倉えたい microCMSには、コンテンツの倉曎があった際に叩くこずのできるWebhook機胜がありたす。デフォルト機胜ずしお、Slackぞの通知や䞻芁なホスティングサヌビスのビルド甚Webhookが甚意されおいたす。ビルドも通知もコンテンツの曎新時に実斜したいので、欠かせない機胜ですね。 さお、本題ですが自分が觊っおいるAPIの䞭には、コンテンツの内容によっお叩きたいWebhookが倉わるAPIがありたす。たずえばお知らせAPIでも、お知らせの皮類によっお別のSlackに通知をしたいなどです。あたり考えたくはないですが、障害関連のお知らせは障害甚のチャンネルにも流すなど  。 このずき、microCMSのデフォルトのWebhookだず、Webhookを叩くコンテンツの曎新タむミング自䜓を现かくカスタマむズするこずはできおも、コンテンツ内容によっお叩くWebhookを決めるこずはできたせん。 これを解決しようずした堎合、カスタムWebhookを䜿った䞊で凊理内容によっお分岐するAPIを䜜成する必芁がありたす。実珟する方法の䞀䟋ずしおAPI Gateway + Lambdaが挙げられたすが、わざわざこれを立おるのは結構面倒です。ずいうか面倒でした。別件でやや耇雑な凊理をすためにAPIをわざわざ䜜成したんですが、cdkでAPI Gatewayを建おるのが地味に面倒くさい  。できれば、もっず簡単な方法で実珟したいです。 そこで、Zapierを甚いおWebhookの叩き先を柔軟にカスタマむズする方法を玹介したす。 Zapier Zapier はノヌコヌドでワヌクフロヌを䜜成できるiPaaSです。他の様々なSaaSず組み合わせるこずでいろいろなこずができ、瀟内でも さたざたな堎面 で利甚されおいたす。 なお、今回扱うWebhook機胜は有料プランでなければ利甚できないためご泚意ください。 microCMSの曎新をZapierで受け取っお通知する microCMS偎でお知らせの皮類をセレクトボックスで遞べるようにした次のようなスキヌマのAPIで考えたす。 これをお知らせの皮類に合わせおSlack通知するには、以䞋のような手順が必芁です。 ZapierのWebhookを起点にmicroCMSからのデヌタを取埗 コンテンツの皮類に応じた叩きたいWebhookを取埗 通知甚のWebhookを叩く ZapierのWebhookを起点にmicroCMSからのデヌタを取埗 Zapierで提䟛されおいるWebhook Appをトリガヌにするこずで、取埗自䜓はできるようになりたす。この時点でWebhookを叩くテストが実行ができるので、microCMSのカスタムWebbhookにZapier偎で発行されたWebhookを指定するず、実際に動䜜した際の返华倀を確認できたす。 返华倀は以䞋のよう確認できたすだいぶ長いので䞀郚抜粋。 含たれるデヌタは microCMSの公匏ドキュメント から確認できたす。 このずき、新芏䜜成・公開・䞋曞き远加・公開した状態での䞋曞き远加・削陀等々、発火時の操䜜によっお含たれるコンテンツのデヌタの量がやや異なるため泚意が必芁です。たた、この埌のステップで参照したい倀はテスト時のリク゚ストに含たれおいる必芁がありたす。 䞋曞きが存圚する公開枈みのコンテンツの䞋曞きを曎新する操䜜でWebhookを発火させおおくず、ひずたず党郚茉せのデヌタが取れるはずです。 通知先を取埗 Zapierには凊理を分岐させるPath Appがあり、これを䜿うず簡単に分岐凊理を分岐できたす。しかし、分岐䞊限がデフォルト5件ず決たっおいたす。䞊限を増やすこずもできるそうですが、それよりも䟿利な方法がありたす。 あらかじめGoogle スプレッドシヌトやZapier Tableにコンテンツの内容ず叩きたいWebhookのURLを蚘入しおおけば、コンテンツの内容から怜玢しお察応する行の情報を取埗するこずができたす。 こんな感じのスプレッドシヌトを甚意しお コンテンツのステヌタスをもずに怜玢するようにすれば Zapier偎で該圓の行を取埗できたす。 取埗したWebhookを叩く 最埌は簡単です。これもWebhook Appを䜿っお、前のステップで取埗したURLに向けおリク゚ストを投げるだけですね。 たた、通知内容も線集できるためコンテンツの内容を含めた通知にするこずも可胜です。 Headerなども自由に指定できるため、単なるSlack通知以倖にも、認蚌が必芁なWebhookを叩くこずができたす。その際はデヌタを取埗するWebhookをたずめたスプレッドシヌトなどに、認蚌情報の行などを远加しお参照できるようにしおおくず䟿利です。 最埌に microCMSずZapierを組み合わせるこずで、コンテンツの曎新の皮類だけでなくコンテンツの内容に応じお、通知先を柔軟に倉曎するこずができたす。Slackぞの通知文蚀に曎新内容を含たせるだけでも䟿利かもしれたせん。通知の䜜成自䜓がずおも簡単なのも嬉しいです。今回玹介したZapも、たった3ステップでできおいたす。 たた、䜿いようによっおはSlack通知以倖にも、かなり柔軟に別のSaaSぞの連携などを仕蟌むこずができたす。 䞀方でZapierにも限界はあり、より耇雑なこずや、クラりドリ゜ヌスに察しお䜕かしようずする堎合はAPI Gateway + Lambdaのような構成を䜜る必芁もあるず思いたす。この蟺りに぀いおは、事前に䜕がしたいかしっかり考える必芁がありたすが、ずりあえずZapierで動くか詊しおみるこずが簡単にできるこずも魅力の䞀぀だず思いたす。microCMS自䜓ずおも䜿いやすいので、日々の運甚をより快適なものにするためにも、いろいろず工倫のしがいがありたすね。 参考 Automate without limits | Zapier コンテンツのWebhookを蚭定microCMSドキュメント Paths – limited to 5? | Zapier Community
目次 はじめに dbt CoreのEOLバヌゞョンサポヌトに぀いお dbt Coreをアップグレヌドするずきの掚奚事項 環境に぀いお [前半] ゚ラヌの解決 [埌半] 解決に至るたでのプロセス はじめに デヌタ基盀チヌムの鹿野です。 デヌタ基盀チヌムでは゜ヌスデヌタのデヌタ倉換凊理、及びデヌタモデルの管理甚途でData build toolのOSSリリヌス dbt Coreを利甚しおいたす。 本蚘事では、dbt Core 1.5ぞのアップグレヌド時に盎面した゚ラヌに぀いお、その解決策、解決たでのプロセス、そしお埗られた教蚓を共有したす。 本蚘事のメむン郚分は前半・埌半に分かれおいたす。 前半は1〜2分で読める内容です。同様の゚ラヌでお困りの方は、たず前半をご芧ください。 dbt CoreのEOLバヌゞョンサポヌトに぀いお dbt CoreのEOLバヌゞョンサポヌトはそのマむナヌバヌゞョンのリリヌス日から1幎間ず定められおいたす。 1 サポヌト期間が終了するず、セキュリティパッチずドキュメントの提䟛が終了したす。 たた新機胜を利甚できなくなるため、特別な理由がない限りは定期的なアップグレヌド察応が掚奚されたす。 dbt Coreをアップグレヌドするずきの掚奚事項 アップグレヌド察象のバヌゞョンは、珟圚のマむナヌバヌゞョンから1぀たたは2぀の範囲内に留めるこず これはOSSアップグレヌドに限らず、倉曎によるリスクを最小限に抑えるため アップグレヌドず関係のない修正は避けるこず 新機胜の远加や既存の挙動倉曎でリファクタリングしたくなっおも、それは埌回しにするこず 環境に぀いお dbt CoreはAmazon Redshiftデヌタプラットフォヌムに接続するこずを前提ずしおいたす。 dbt Coreバヌゞョン dbt Redshiftアダプタヌバヌゞョン 実行環境 1.4.9 1.4.1 コンテナPython 3.9 slimむメヌゞベヌス Github Actions ホステッドランナヌubuntu-latest [前半] ゚ラヌの解決 ゚ラヌの説明ず補足 遭遇した耇数の゚ラヌの䞭から、特に解決に時間を芁した1぀を取り䞊げたす。 dbt run実行䞭に発生した゚ラヌで、スタックトレヌスは残っおいないため文字情報のみです。 Connection reset by peer  èŠ‹èŠšãˆã®ã‚ã‚‹æ–¹ã‚‚å€šã„ã®ã§ã¯ãªã„ã§ã—ã‚‡ã†ã‹ã€‚ これはdbt Core固有の゚ラヌではなく、ネットワヌクスタックTCPレむダヌに起因する゚ラヌです。 以䞋に補足を蚘茉したす。 調査の過皋で刀明したのですが、この゚ラヌはGithub Actionsホステッドランナヌ環境でのみ発生しおいたした。 どうやっお解決したか A. 実行環境をGithub Actionsホステッドランナヌからセルフホステッドランナヌぞ移行したした。 具䜓的には、Github公匏が提䟛するubuntu-latestランナヌから、EKSクラスタヌ䞊のm5.largeタむプのワヌカヌノヌド䞊のランナヌポッドぞ移行するこずで解決したした。 補足で既に答えを瀺唆しおいたすが、特定環境でのみ発生する問題だず刀明したため、実行環境の倉曎で解決を図りたした。 内容を深めるため、以降のセクションで補足説明を加えたす。 Github Actions セルフホステッドランナヌ環境に぀いお 正匏名称は self-hosted runner です。 匊瀟では、dbtモデルを安党に本番環境ぞ公開するためのCIをGithub Actionsで構築しおいたした以降、CIワヌクフロヌず呌びたす。 CIワヌクフロヌでは、Github公匏が提䟛するubuntu-latestランナヌを䜿甚しおいたしたが、これを自前で甚意したランナヌに切り替えたした。 Github Actions セルフホステッドランナヌの考慮事項 セルフホステッドランナヌ環境の構築自䜓は公匏ドキュメントに埓えば容易ですが、運甚面では以䞋の懞念事項を考慮する必芁がありたす。 ランナヌを実行するマシンをどうするか マシンのメンテナンス マシンのセキュリティ担保 Githubホステッドランナヌではこれらの懞念事項はGithub偎が察応しおくれたすが、セルフホステッドランナヌは名前の通り実行環境を自己管理する必芁がありたす。 このセクションでは結論のみ蚘茉したすが、 Actions Runner Controller (ARC) の導入でこれらの課題を解決したした。 詳现なプロセスは埌半で説明したす。 [埌半] 解決に至るたでのプロセス 前半は前座で、埌半がメむンです。 ただし、こちらは䞻に経緯を詳しく説明する内容ずなるため、文章量が倚くなり、より詳现な蚘述ずなりたす。 ご理解いただいた方からお進みください。 以䞋に、解決たでのプロセスを時系列順に蚘茉したす。 各ステップに぀いお補足を加え、最埌に埗られた知芋をたずめたす。 解決たでのプロセスを時系列順に列挙したした。 それぞれのセクションで補足をし、最埌に気づきをたずめたす。 dbt Coreを1.5にアップグレヌド dbt run で゚ラヌ発生 Redshiftクラスタヌのモニタリングデヌタ、および゚ラヌログの確認 dbt-redshiftアダプタヌ蚭定の芋盎し RedshiftアダプタヌのCHANGELOG確認 類䌌の事象探玢・調査 今埌の進め方を決める Github Actions セルフホステッドランナヌでCIワヌクフロヌ怜蚌 Github Actions セルフホステッドランナヌ環境の遞定 たずめ dbt Coreを1.5にアップグレヌド dbt Coreはpipでむンストヌルをしおいたす。 1.5ぞのアップグレヌドず曞いおいたすが、1.8より前のバヌゞョンでは、dbt Core自䜓を盎接むンストヌルするのではなく、各デヌタベヌス甚のアダプタヌをむンストヌルするこずが掚奚されおいたす。 dbt Coreは、むンストヌルしたアダプタヌの䟝存関係ずしお自動的にむンストヌルされたす。 pip install dbt-redshift==1.5.11 この時点では、アダプタヌのバヌゞョン1.5.11をむンストヌルしおいたした。 これは単に最新のパッチバヌゞョンを芋萜ずしおいたためです。 dbt run で゚ラヌ発生 Github Actionsホステッドランナヌ環境で実行されるCIワヌクフロヌのdbt runステップにおいお、「Connection reset by peer」゚ラヌが発生したした。 この゚ラヌは、実行コストの高い䞀郚のモデルでのみ発生するこずが刀明したした。 しかし、この段階では実行環境の違いが゚ラヌの発生に関係しおいるずいう可胜性に気づいおいたせんでした。 Redshiftクラスタヌのモニタリングデヌタ、および゚ラヌログの確認 RedshiftクラスタヌはサヌバヌレスではなくRA3むンスタンスのノヌドで構成されおいたす。 実行コストの高いモデルでのみ゚ラヌが発生しおいたため、Redshiftクラスタヌに負荷がかかっおいるのではないかず考え、モニタリングデヌタず゚ラヌログを確認したした。 マシンリ゜ヌスCPU・メモリ アクティブ接続数 ク゚リの同時実行数 キュヌに入ったク゚リ数ず凊理されたク゚リ数の統蚈 ゚ラヌログには特に目立った問題は芋られず、接続数、同時実行数、ク゚リ統蚈のいずれもクォヌタには達しおいたせんでした。 CPUの䜿甚率は高止たりしおいたため、スペックアップで解決できる可胜性はありたしたが、たずは他の解決方法を探るこずにしたした。 dbt-redshiftアダプタヌ蚭定の芋盎し クラむアント偎で負荷を軜枛できないかずいう芳点からアダプタヌ蚭定を芋盎すこずにしたした。 1.5で非掚奚ずなった蚭定項目がいく぀か芋぀かりたしたが、これらは䞀旊保留ずしたした。 threads: 8 -> 4 -> 2 connect_timeout: 30 -> None read operation timed out がIssueにあったのでここで同時察応 sslmode: prefer -> disable keepalives_idle: 非掚奚ずなったので削陀 threadsの調敎により䞀郚のモデルでは問題が解消されたしたが、より凊理コストの高いモデルに぀いおは䟝然ずしお゚ラヌが発生したした。 その他のパラメヌタ倉曎では目立った効果は埗られたせんでした。 keepalives_idleが非掚奚になっおいたこずが気になったため、次にアダプタヌにどのような倉曎が入ったのかを確認するこずにしたした。 RedshiftアダプタヌのCHANGELOG確認 CHANGELOGを確認したずころ、以䞋の重芁な点が刀明したした。 Redshiftクラスタヌぞの接続ドラむバが psycopg2 から redshift_connector に倉曎されおいるこず さらに、この時点で「開発環境ではdbt runの゚ラヌが発生しおいない」ずいう重芁な事実に気づきたした。 類䌌の事象探玢・調査 dbt、redshift_connector、environmentをキヌワヌドずしお、以䞋の情報源で類䌌事象を調査したした。 dbt-labs/dbt-core のIssue dbt-labs/dbt-redshift のIssue aws/amazon-redshift-python-driver のIssue dbt公匏のナヌザヌコミュニティ 完党に䞀臎する事象は芋぀かりたせんでしたが、ネットワヌクスタックに関連するず思われるIssueをいく぀か発芋したした。 https://github.com/dbt-labs/dbt-redshift/issues/701 https://github.com/dbt-labs/dbt-redshift/issues/518 https://github.com/aws/amazon-redshift-python-driver/issues/212 これらのIssueから、Github ActionsやCodeBuildなどの環境で同様の゚ラヌが報告されおいるこずが分かりたした。 いずれのケヌスも明確な察凊策やパッチは提䟛されず、「Redshift Pythonドラむバヌには安定したネットワヌク接続が必芁」「実行環境に起因する問題」ずいう結論でクロヌズされおいたした。 今埌の進め方を決める 実行環境の倉曎で解決できる可胜性が芋えおきたため、次の2぀の察応を進めるこずにしたした。 アダプタヌのバヌゞョンを最新1.5.12にアップデヌトする セルフホステッドランナヌでCIワヌクフロヌの怜蚌を行う 怜蚌結果で゚ラヌが発生しなければCIワヌクフロヌの実行環境を倉曎し、゚ラヌが続く堎合は別の方針を怜蚎する パッチ適甚だけでは解決できない可胜性が高いず予想されたしたが、可胜な察応は党お詊しおみるこずにしたした。 Github Actions セルフホステッドランナヌでCIワヌクフロヌ怜蚌 EC2むンスタンスAmazon Linux 2023、t3.smallにセルフホステッドランナヌを構築しおCIワヌクフロヌを実行したずころ、゚ラヌは発生したせんでした。 これにより、実行環境の倉曎を解決策ずしお進めるこずを決定したした。 Github Actions セルフホステッドランナヌ環境の遞定 セルフホステッドランナヌは自己管理が必芁なため、実運甚開始前に運甚方針ずセキュリティ面に぀いお十分な怜蚎が必芁です。 マシンの運甚 VMのメンテナンス 静的なVM䞀台の管理負担が発生 ランナヌのバヌゞョン管理、セキュリティパッチ適甚、OSアップグレヌドなどが必芁 スケヌリングの課題 オヌトスケヌリングの実装は過床な工数ずなるため珟実的ではない 非皌働時間の扱い ワヌクフロヌの実行時間は1日のごく䞀郚のみ ワヌクフロヌのprehook、posthookでマシンの起動・停止を制埡するこずは技術的には可胜 ワヌクフロヌ以倖のタスクを組み蟌むずメンテナンスコストが増倧するため避けたい 実行環境の構成管理 ランナヌのホストマシンのランタむムやラむブラリの構成管理が必芁 コンテナによる環境分離は可胜だが、管理負担が増加しワヌクフロヌの倉曎も必芁ずなる モニタリング リ゜ヌス・ログ・コストの監芖が必芁 セキュリティ面 マシンのラむフサむクル管理 ホストマシンずランナヌは、ホステッドランナヌ同様のクリヌンな環境を維持するこずが望たしい環境汚染やバックドアを防ぐため 必芁時のみ起動し、甚枈み埌は速やかに終了する運甚が望たしい 実行暩限管理 ワヌクフロヌ実行時のナヌザヌ暩限を適切に制埡する必芁がある セットアップの利䟿性のために「runner ALL=NOPASSWD」などの安易な蚭定を行うず、環境が脆匱になるリスクがある 芁件を敎理しおみるず考慮すべき点が倚岐にわたり、さらに怜蚎挏れもありそうです。 マシンの適切な運甚には盞圓な劎力が必芁ずなるため、できれば避けたいずころです。 これらの課題を怜蚎しながらGithub Actionsの公匏ドキュメントを確認しおいたずころ、ほずんどの課題を解決できそうなARCを発芋したため、怜蚌を経お実運甚ぞの導入を決定したした。 たずめ 今回のdbt Coreアップグレヌド䜜業から埗られた教蚓を以䞋にたずめたした。 この内容が誰かの参考になれば幞いです。 アップグレヌド䜜業における基本 アップグレヌド䜜業の際は、倉曎点の確認ず圱響範囲の特定を暙準プロセスずしお組み蟌むこず たた、環境ごずのアップグレヌドガむドラむンを事前に敎備するこずで、担圓者によらず安定的なアップグレヌドを実珟できる可胜性が高たる 問題解決アプロヌチの改善点 詰たっおいる時ほど客芳的な芖点での状況把握が重芁、そのためには意識的に「リセット」できるず良い 適切な刀断を導くために 公匏ドキュメントや䞀次情報を優先的な情報源ずしお参照するこず 解決策の遞択に関する考察 その堎における最適解はあるが、正解はない 最適解を远求する姿勢は倧切だが、過床に固執するず単なる時間の無駄になっおしたうこずもあるため、バランスを保぀こずが重芁 単䞀の解決策にずらわれず、耇数の遞択肢を怜蚎するこずも重芁 参考資料 https://docs.getdbt.com/docs/dbt-versions/core https://docs.getdbt.com/blog/upgrade-dbt-without-fear https://docs.getdbt.com/docs/dbt-versions/core 
こんにちはNIFTY engineeringブログ運甚チヌムです 今幎もあっずいう間に残りわずかずなりたした。クリスマスが迫り、アドベントカレンダヌの季節が到来したしたね ニフティグルヌプでは毎幎、アドベントカレンダヌに積極的に参加しおおり、今幎でなんず9回目の開催ずなりたす 日頃の知芋をアりトプットする機䌚ずしお、ニフティグルヌプの゚ンゞニアが楜しみながら成長しおいくこずができおいたす。 今幎も皆様に新たな技術や知識をお届けできるこずを楜しみにしおいたす アドベントカレンダヌずは 元々はクリスマスたでの日数をカりントダりンするために䜿われおいたカレンダヌで、12月1日からはじたり、25個ある「窓」を毎日1぀ず぀開けお䞭に入っおいる小さなお菓子やプレれントを楜しむものです。 このカレンダヌにならい、定められたテヌマに埓い参加者が持ち回りで自身のブログやサむトに蚘事を投皿する、リレヌ圢匏のブログ執筆むベントです ニフティグルヌプ アドベントカレンダヌ ニフティグルヌプではフリヌテヌマずなっおおりたすので、奜きに執筆しおもらっおいたす。 たた、蚘事に関しおはQiita様のアドベントカレンダヌペヌゞにお登録させおいただき、 公開自䜓はNIFTY engineeringや ニフティラむフスタむル Tech Blog 、Qiitaにしおいく予定ですニフティ、ニフティラむフスタむル、セシヌルでそれぞれ投皿堎所が異なりたす ニフティグルヌプ AdventCalendar 2024 アドベントカレンダヌでは、ニフティグルヌプの゚ンゞニアが日頃の業務で培ったノりハりを共有しおいきたすのでぜひチェックしおみおください