OmniAICreator/Qiita-1.07M huggingface dataset:
【 初心者向け 】WIndows11でOpenSSHインストールやってみた（GUI編）

# 概要
Windows11でのOpenSSHサーバのインストールを**PC初心者**でも分かるように実践します。
これから`リモートサーバへのアクセス`や`クラウド環境での作業`を始める方は**必見**です。





# OpenSSHをインストール
まず、ここではインストールの手順を解説します。
PCの`スタートボタン`から`設定`を開き、左のタブから`システム`を押下して`オプション機能`を選択します。


![名称未設定ファイル.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935887/670cf7f2-1fc7-538b-a007-1b88ca7c31a2.png)


次に、`機能を表示`を押下してポップアップの検索欄に`OpenSSH`入力し、チェックボックスにチェックを入れて`次へ`を押下して追加する。

![名称未設定ファイル.drawio (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935887/eedb4561-9c89-e533-eae9-d9d986f0dd7e.png)

`最近のアクションの`状態が`追加済み`になれば、OpenSSHのインストール完了です。


![名称未設定ファイル.drawio (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935887/d1922e98-0a6d-ce45-f655-b76644a02800.png)

:::note info
ひとまずこれでOpenSSHのインストールは終了です。
お疲れさまでした。以外にも簡単でしたかね？

個人的にはインターネットで検索してダウンロードすると思っていたのですが、Windowsの設定からインストールできるとは驚きでした。

それでは、次はセットアップです。一緒に頑張りましょう。
:::


# サーバを起動
次に、ここではインストールしたサーバの起動方法を解説します。

キーボード上で`Windows`ボタンと`r`ボタンを同時に押し、"**ファイル名を指定して実行**"のウィンドウを呼び出します。


![名称未設定ファイル.drawio (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935887/ba5d385c-2f87-da54-42c9-fb9d4686384f.png)







:::note info
### Geekポイント
`Windows`＋`r`のショートカットは様々なプログラムなどをWindowsPC上で呼び出すことができ、実務では毎日使う**超必須スキルです。**
今回を機にぜひ習得しましょう。

※呼び出せるプログラムなどの例
・`notepad`→　メモ帳
・`cmd`→　    コマンドプロンプト
:::

呼び出したウィンドウに`services.msc`と入力し、`OK`を押下します。

:::note warn
`services.msc`はWindowsにインストールされている管理ツール **「サービス」** を呼び出すためのファイルであり、**「サービス」** はPC起動時などに開始されるプログラムなどを管理できるコントロールパネルです。
:::

![名称未設定ファイル.drawio (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935887/764c7c5f-fd4b-4aca-4dac-e1f542e7763e.png)

`サービス（ローカル）`をスクロールし、`OpenSSH SSH Server`をダブルクリックします。

![名称未設定ファイル.drawio (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935887/75604aaf-5b1e-4e1a-b811-8d83fe1f499f.png)

プロパティのポップアップが表示されたら`スタートアップの種類(E)`を`自動`に、
`サービスの状態`を`開始`にして`OK`を押下します。
![名称未設定ファイル.drawio (7) (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935887/a222cf79-fc22-7dbb-a318-d57d481ecdad.png)


:::note info
以上でOpenSSHサーバの起動は終了です、お疲れさまでした。
:::

# 作業を終えて…
**ここまでの作業、お疲れさまでした！**
OpenSSHのインストール方法は様々ありますが、今回はGUIでの操作でしたので、慣れ親しんだPC画面やマウスでの操作で直感的に手順を進めることができたと思います。
次はCUIでの方法や他サーバからOpenSSHに接続する方法なども気が向いたら投稿してみようかと思います！
平均関数、分散関数からベイズ最適化へ

以下、ガウス過程の途中計算から

https://qiita.com/saka1saka/private/b8b6c834545276cbdeb6

前回はガウス過程における$\mu(x)$および$\sigma^2(x)$の値を算出した。
これらが分かればブラックボックス関数の最小化$\min_{\mathbf{x}} \{ f(\mathbf{x}) \}$を直接計算することなく関数の予測を行うことができる。
すなわち、以下を求ればいい。
```math
\min_{i} \{ \mu(\mathbf{x}_i) \}


```
(多変量)ガウス分布とは、そのMAP推定値が丁度、出力$\mu$と等価である。
そのため、$\mu(x)$をブラックボックス関数の代わりに扱うことができる。

:::note warn
多変量ガウスの補足：
```math
p(\mathbf{y}_n) = \frac{1}{\sqrt{(2\pi)^n |\Sigma_n|}} 
\exp\left( 
-\frac{1}{2} (\mathbf{y}_n - \boldsymbol{\mu}_n)^\top \Sigma_n^{-1} (\mathbf{y}_n - \boldsymbol{\mu}_n)
\right)

```
以上のように最大値は$y$=$\mu$となることがわかる。
:::
----------------
下図のように平均関数(青線)上の点はガウス分布の平均となる。
なお、平均関数を取り囲む水色の大枠はベイズ信用区間を表している。その幅は各点におけるガウス分布の区間幅に対応している。

![スクリーンショット 2024-12-29 23.16.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924643/f4faed24-f7ec-0cfd-6d59-d686e22144ec.png)

## 最適点の求め方について
平均関数と分散関数を求めることができたが、(ブラックボックス関数の代わりである)平均関数の最小値を具体的にどう求めるか。

色々やり方はあるかもしれないが、ここでは獲得関数によって最小値を探索することにする。

### 獲得関数とは何か?
端的に言うと、最小値などの最適点をどう見つけるかといった***方策***を表す関数である(と、私は考えている)。
もちろん、状況に応じて適した方策が存在するため、獲得関数はたくさん考えられている。

例として、シンプルな獲得関数を以下に示す。

```math

\alpha(x) 
= -\bigl(\mu(x) \;-\; \sqrt{\beta}\,\sigma(x)\bigr)

```
```math
ただし、\arg_{\max x}\,\alpha(x)
```

この関数は信頼下限獲得関数と呼ばれる。$\arg_{\max x}\,\alpha(x)$とあるように、獲得関数が最大となるような変数が平均関数の最適点となる。

この式を見てみると、$\beta$が$\sigma(x)$を調整しているハイパーパラメータであることがわかる。
例えば、$\beta$がゼロなら、獲得関数は$\mu(x)$のみに依存する。これが意味することは、平均関数そのものを最小化すればいいことになる。一方、$\beta$に値があれば、$\sigma(x)$も考慮した最大化がなされる。
前者の場合、今まで得たデータから最適点を求めるが、一方、後者では、分散関数という不確実性の振れ幅を考慮した探索となる。

つまり、獲得関数とは***利用と探索のトレードオフ***の関係になっているのだ。

繰り返すと、今まで学習したデータから最適点を見つけてしまうのか、まだまだ怪しい領域があると思い探索していくのか

このことを表現している。

そして、このような獲得関数を持ってガウス過程における最適点を探すことを***ベイズ最適化***と呼ぶ。
DockerでWordPressを試してみる①

# はじめに
WordPressはよく聞きますが、仕事として触ったことはありませんでした。
縁あって、触る必要がでてきましたので、簡単にどんなものか勉強がてら試してみます。

# 環境
OS:AlmaLinux9

# 参考情報
以下のサイトを参考に作業しています。

https://github.com/docker/awesome-compose/tree/master/official-documentation-samples/wordpress

# docker-compose.ymlの準備
適当な(project)ディレクトを作成して、以下のサイトから取得した
docker-compose.ymlを配置します。
内容？こまけぇこたぁいいんですよ。

https://github.com/docker/awesome-compose/tree/master/wordpress-mysql

# docker-compose.ymlの編集
DBデータはVolumesでホストとバインドされていますが、
wordpressの紐づきは記載ないので追加していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/df480810-dbfa-d294-a518-19d943c2437f.png)

# ビルド
以下のコマンドで、ビルドしていきます。
```
docker compose up -d
```

さっそく権限ないぜって言われたので、付与。
```
sudo chmod 666 /var/run/docker.sock
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/100ff900-9cc1-53b3-c8fe-eb0c5d96edc2.png)

再度、docker compose upコマンドを実行し、無事にビルドできたようです。

<br/>

さっそく、ホスト側のブラウザから確認していきます。
URLはdockerが動いている端末のポート:50になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/66d6687c-50d4-12d0-e23b-06efe7f3ce94.png)

おぉ、普通にセットアップ画面ですね。
次回は設定何やらをすすめていきます！
一瞬だけScala案件やってて、Javaに戻りテストコードを書いてて思ったこと

# Scalaとは全然関係ない話です。

あとで書き直します。

Scalaの案件に携わり、関数型言語とは......みたいなものを学ぼうとしていたら離プロして結局果たせずじまい。

その後、別案件でテストカバレッジチームに配属されました。
既存のプロダクトコードにJUnitでテストを書いていく、それだけです。
そして依存関係が少なく、独立したメソッドなら `Mockito` さまさまで楽にかけます。

しかし困るのが、パラメーターやパラメーターに使われるオブジェクトの一部が違うパターン。
もちろんJUnit5などでは `@Parameterizedtest` などの便利な機能が用意されてはいますが、それだけで充当できるわけでもなく。

もちろん共通部分をメソッドに切り出す、という手段を使いつつも、やはりどうにも同じメソッドを呼び出している感が拭えないし、柔軟性がないような気がする。

そしてもう一点。
たとえば `@BeforeEach/@BeforeAll` や `@AfterEach/@AfterAll` に含めたくないけど、シングルトンやstaticなフィールドにモックを突っ込みたいとき。
既存テストに影響を与えず、という形です。

もちろん各テストメソッド内で、設定する/解除する、というのを組み込めばいいのですが、しょせん人間、間違いはあります。最悪の場合、モックが設定されたまま使い回される可能性もあり、テスト品質に影響がでます。

そんなこんなで思い当たったのが、Scalaをやっていたときに学んだローンパターンや関数型インターフェースの組み合わせ。


```java
private void withMock(Consumer<MotoniModoshitaiResource> c) {
    MotoniModoshitaiResource mock = Mockito.mock(MotonimodoshitaiResource.class);
    MotoniModoshitaiResource moto = Taisho.mmr;
    reflectionTokadeMuriyariSet(mock);
    c.accept(mock);
    reflectionTokadeMuriyariSet(moto);
}

@Test
void testHoge() {
    withMock(c -> {
        // テストコード書く
        // ここのcはモックなのでverifyとかも可能
    });

}
```

これなら使っている側は、静的クラスや外部リソースの復元を気にすることなく、メソッド呼び出し内でテストを記述するだけでことたります。
また上記のような考え方をすることで、微妙に異なるフィールド値を使うテストも差分だけを書けばよくなるような気がします。
パラメーターが `NanrakanoObj` の各フィールドの値の違いによるテストを書きたければ
`Consumer<NanrakanoObj>` を引数に持つメインテストケースを共用すればいいのです。

```java

private Result testFieldDakeChigau(Consumer<Target> c) {
    Target t = new Target();
    t.setName("..."); // 共通的な設定
    /* 共通的な処理 */
    c.accept(t); // ここで各パターンで違うことをする
    Result r = xxx.exec(t);
    assertEquals(r.name(), "..."); // 共通的なテスト
    return r;
}

@Test
void test1() {
    Result r = testFieldDakeChigau(c -> c.setStatus("x"));
    assertEquals("X", r.getStatus());
}

@test 
void test2() {
    Result r = testFieldDakeChigau(c -> c.setType("b"));
    assertEquals("B", r.getType());
}

```
Windows向け関数電卓ソフトの紹介（先日投稿した記事の補足）

# 先日投稿した記事の補足

## ↓先日投稿した記事↓
https://qiita.com/techem_it/items/befa5684de4decd48d05

## 他ブログでの紹介
現在coconala様で販売している、私が開発したWindows向け関数電卓ソフト「SCalc」をBloggerの方で紹介記事を投稿しているのですが、まだブラウザでの検索にヒットしないので、こちらで紹介させていただきます。

<b>↓Bloggerの記事↓</b>
https://chem-it.blogspot.com/

それに伴い、以下2つのブログを開設して記事を投稿しております。
https://ameblo.jp/techem-it/entry-12878142402.html

https://note.com/chemitech/n/nff565d1290e4

amebloもnoteもまだインデックス化されていないので、こちらで紹介させていただければと思います。

昨日は製品紹介動画を作成していたのですが、youtubeに投稿したところ解像度や縦横比がひどいことになっていたので、もう少し動画作成の勉強をしようと思いました。
現在非公開としております。
12日目: SparseTableを実装する

[競プロ用ライブラリを作る Advent Calendar 2024](https://qiita.com/advent-calendar/2024/yukkku-ribitol)の12日目です.

https://qiita.com/advent-calendar/2024/yukkku-ribitol

# SparseTableって?

長さ$N$の列が与えられたとき,「指定された区間の最小値を求めろ」のようなクエリを$O(1)$で処理できるデータ構造です.
ただし構築には$O(N\log N)$かかります.

# 仕組み

区間の最小値を求めるSparseTableを実装することを考えます.
長さ$N$の数列$x_0,x_1,\dots,x_{N-1}$について, 区間$[l, r)$の最小値を$x[l, r)$と書くことにします.

クエリを$O(1)$で処理したいだけなら, 全ての区間の答えを計算しておけばいいですが, 区間が$\Theta(N^2)$個あるのでこの方法は構築に$\Omega(N^2)$かかってしまいます.

SparseTableは幾つかの区間の情報だけ前計算しておいて, クエリで与えられる区間を前計算した区間2つの組み合わせで表現できるようにします.

例えば長さ5の数列が与えられたとき, $x[0,1), x[1,2), x[2,3), x[3,4), x[4,5), x[0,3), x[1,4], x[2,5)$の8つの情報を持っておけば, その中から2つ選んで全ての区間での答えを復元できます.
注目すべきが$x[0,5)$というクエリで, $\min(x[0,3),x[2,5))$という風に計算します. 持ってる情報が最小値なので区間に重複が出ても問題ないのがポイントです.

ここからはパズルです. 持つ情報を減らしつつ全ての区間の答えを2つの情報の組み合わせで表現するにはどうするのが効率的でしょうか.

AtCoderにそういう問題もあるのでどうぞ

https://atcoder.jp/contests/abc282/tasks/abc282_f

答えの1つが「長さが2の冪の区間の情報だけ持つ」です.
例えば$x[l, r)$というクエリを捌くには長さ$M=2^{\lfloor\log_2(r-l)\rfloor}$の区間を2つ組み合わせます.
$x[l, r) = \min(x[l,l+M), x[r-M,r))$という感じですね. $M\le r-l$なので, これでクエリの区間からはみ出さず, クエリの区間内の全ての要素を捉えることが出来ます.
純粋に何も知らずに考察したら「長さが2の冪-1の区間の情報を持つ」になりそうですが, 2の冪の区間の情報を持った方がデータ量は少し増えますがちょっと簡潔になります.

# 実装

- [`sparsetable.rs`](https://github.com/Yukkku/ribitol/blob/main/src/sparsetable.rs)

配列1つに頑張って全部の区間の情報を並べました. 計算をゴリゴリしたら出ます.

# まとめ

いかがでしたか?

明日は今日に引き続き, 別にSegmentTreeで十分な気もするデータ構造を実装します.
[Delphi][小ネタ] メルセンヌ・ツイスタ

# はじめに
[９日](https://qiita.com/pik/items/c3530f222a99365b32d2)、[１１日](https://qiita.com/pik/items/7b224f3cd9f7c3603e9c)に引き続き乱数の話です。

今回はメルセンヌ・ツイスタについてです。

# メルセンヌ・ツイスタとは

[Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%A1%E3%83%AB%E3%82%BB%E3%83%B3%E3%83%8C%E3%83%BB%E3%83%84%E3%82%A4%E3%82%B9%E3%82%BF) によると

> メルセンヌ・ツイスタ (Mersenne twister、通称MT) は擬似乱数列生成器の1つである。
> 既存の疑似乱数列生成手法にある多くの欠点がなく、高品質の疑似乱数列を高速に生成できる。考案者らによる実装が修正BSDライセンスで公開されている。

とのことで、周期がメッチャ長い（$2^{19937} - 1$）、生成される乱数の質が高い、などの特徴があります。
デメリットは計算資源を結構使う（メモリ・CPU）事です。

# 実装
Delphi での実装はこんな感じです。
長いので折りたたみます。

<details><summary>メルセンヌ・ツイスタ</summary>

```delphi
unit PK.Math.MersenneTwister;

{$OVERFLOWCHECKS OFF}

interface

uses
  System.SysUtils;

type
  TMersenneTwister = record
  private const
    N = 624;
    M = 397;
    MATRIX_A =   $9908B0df;
    UPPER_MASK = $80000000;
    LOWER_MASK = $7fffffff;
  private class var
    FMatrix: array[0.. N - 1] of UInt32;
    FIndex: Integer;
  private
    class procedure Twist; static;
  public
    class procedure Init; static;
    class procedure SetSeed(const ASeed: UInt32); static;
    class function Execute: UInt32; static;
  end;

implementation

{ TMersenneTwister }

class function TMersenneTwister.Execute: UInt32;
begin
  if FIndex >= N then
    Twist;

  var Y := FMatrix[FIndex];
  Inc(FIndex);

  // Tempering
  Y := Y xor (Y shr 11);
  Y := Y xor ((Y shl 7) and $9d2c5680);
  Y := Y xor ((Y shl 15) and $efc60000);
  Y := Y xor (Y shr 18);

  Result := Y;
end;

class procedure TMersenneTwister.Init;
begin
  RandSeed := 5489; // Default Seed (mt19937)
  SetSeed(RandSeed);
end;

class procedure TMersenneTwister.SetSeed(const ASeed: UInt32);
begin
  FMatrix[0] := ASeed;

  for var i := 1 to N - 1 do
    FMatrix[i] := 1812433253 * (FMatrix[i - 1] xor (FMatrix[i - 1] shr 30)) + i;

  FIndex := N;
end;

class procedure TMersenneTwister.Twist;
begin
  for var i := 0 to N - M - 1 do
  begin
    var Y := (FMatrix[i] and UPPER_MASK) or (FMatrix[i + 1] and LOWER_MASK);
    FMatrix[i] := FMatrix[i + M] xor (Y shr 1) xor (MATRIX_A * (Y and 1));
  end;

  for var i := N - M to N - 2 do
  begin
    var Y := (FMatrix[i] and UPPER_MASK) or (FMatrix[i + 1] and LOWER_MASK);
    FMatrix[i] := FMatrix[i + (M - N)] xor (Y shr 1) xor (MATRIX_A * (Y and 1));
  end;

  var Y := (FMatrix[N - 1] and UPPER_MASK) or (FMatrix[0] and LOWER_MASK);
  FMatrix[N - 1] := FMatrix[M - 1] xor (Y shr 1) xor (MATRIX_A * (Y and 1));

  FIndex := 0;
end;

end.
```
</details>

# サンプル
[前回、前々回](https://qiita.com/pik/items/c3530f222a99365b32d2#%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB)と同じサンプルを動かしてみました。

結果はこうなりました。

```console
0 975
1 1020
2 1027
3 993
4 969
5 968
6 953
7 990
8 1077
9 1029
```

特に代わり映えはしないですね。

# まとめ
一般的なプログラムでメルセンヌ・ツイスタ程の強度を持つ乱数が必要な事はほとんど無いでしょう。
計算資源も多く使うため、使い所が難しいかもしれません。
また、メルセンヌ・ツイスタも暗号用には使えません。

反面、科学技術計算などでは周期の長さが役に立つかも知れません（[モンテカルロ法](https://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%B3%E3%83%86%E3%82%AB%E3%83%AB%E3%83%AD%E6%B3%95)を試す時とか）

乱数はゲーム業界では必須の機能で、機能に応じてアルゴリズムを使い分けたりしますが、SIer が手がける分野のプログラムではあまり使用しないと思います（宝くじぐらい？）。
そのため、紹介記事を書いてみました。
Webブラウザの拡張機能を作ってみよう

<!-- Webブラウザの拡張機能を作ってみよう -->

※この記事は[Udon Advent Calendar 2024 - Adventar](https://adventar.org/calendars/10764)の12日目の記事です。

## はじめに

こんにちは。Udonです。

今回はWebブラウザの拡張機能を作ってみた話をしようと思います。

## 作ったもの

[Gitudon/URL_and_Title](https://github.com/Gitudon/URL_and_Title)というリポジトリに、作った拡張機能のソースコードがあります。

ブラウザで開いたページのタイトルとURLを取得し、マークダウン形式でクリップボードにコピーする拡張機能を作りました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3468660/9410711f-6227-2545-a0c9-aaeb1f7b7004.png)

こんな感じで、右クリックして開いたコンテキストメニューから「Copy MarkDown Link and Title」をクリックすると、クリップボードに以下のような文字列がコピーされます。

```
[Gitudon/URL_and_Title](https://github.com/Gitudon/URL_and_Title)
```

## 使い方

上記のリポジトリのREADMEに書いてある通りですが、手順としては以下のようになっています。

### Chrome

1. このリポジトリをクローンするか、ZIPファイルでダウンロードして解凍します。
2. Chromeの拡張機能のページを開きます。
3. 右上のデベロッパーモードを有効にします。
4. 「パッケージ化されていない拡張機能を読み込む」をクリックして、このリポジトリのディレクトリを選択します。
5. 拡張機能が追加されます。

### Edge

1. このリポジトリをクローンするか、ZIPファイルでダウンロードして解凍します。
2. Edgeの拡張機能のページを開きます。
3. 「開発者向け設定」の「拡張機能の開発者向け機能を有効にする(これによりデバイスが危険にさらされる可能性があります)」にチェックをつけEdgeを再起動します。
4. 右上の設定から「拡張機能」をクリックします。
5. 「展開して読み込み」をクリックし、このリポジトリのディレクトリを選択します。
6. 拡張機能が追加されます

## 仕組み

``manifest.json``と``background.js``だけで作られており、非常にシンプルな構成になっています。

``manifest.json``には拡張機能の設定が書かれています。

```json
{
    "name": "MarkDown-URL_and_Title",
    "author": "Udon",
    "version": "1.0",
    "manifest_version": 2,
    "description": "URLとタイトルをMarkDownのリンク形式で取得します。",
    "background": {
        "scripts": ["background.js"],
        "persistent": true
    },
    "permissions": [
        "contextMenus"
    ]
}
```

名前、作者、バージョン、説明、``background.js``の指定、``contextMenus``の許可が書かれています。

``background.js``には拡張機能の動作が書かれています。

```javascript
//Edge の名前空間(browser) がなけれぱ chrome の名前空間を使用する
var browser = browser||chrome;

//コンテキストメニューに拡張のメニューを追加
browser.contextMenus.create({
    id: 'MarkDownLink',
    title: 'Copy MarkDown Link and Title',
        onclick: (info, tab)=>{ //クリックされた際のアクション
            var url = tab.url;
            var title = tab.title;
            var markdown = '[' + title + '](' + url + ')';
            toClipBoard(markdown);
            function toClipBoard(text){
                var ta = document.createElement("textarea");
                ta.value = text;
                ta.style.position = "fixed";
                ta.style.left = "0";
                ta.style.top = "0";
                document.body.appendChild(ta);
                ta.select();
                document.execCommand("copy");
                ta.parentElement.removeChild(ta);
            }
    }
});
```

名前空間を指定した後、コンテキストメニューに拡張メニューを追加していきます。クリックされた際にどのようなアクションをするかなどを規定するわけです。

今回は、クリックされた際にタブのURLとタイトルを取得し、MarkDown形式でクリップボードにコピーするようにしています。コピーするための関数は``toClipBoard``として定義しています。

## おわりに

この拡張機能を作ったことで、MarkDownで記事などを書くときに参考文献を載せることが非常に簡単になりました。

意外と簡単に拡張機能が作れることがわかったので、今後も何か思いついたら作っていきたいなと思いました。

ではまた、明日の記事でお会いしましょう。

## 参考文献

[ブラウザの拡張機能を自作してみた #JavaScript - Qiita](https://qiita.com/m_hama123/items/aa3101478a8458d61689)
GitHub PR作成時にmainブランチとマージしたコードでテストする

# やりたいこと

GitHubでPull Requestを作成すると、CIで自動的にテストが走る構成にしていることが多いかと思います。その際、そのブランチ上でのテストは通っても、mainブランチ（デフォルトブランチがmasterのケースもあるかと思いますが、以降はmainとして記述します）にマージしたらテストが失敗することが、稀によくありませんか？

並行していた別のブランチでの対応が先にマージされ、そこに自PRでの対応と矛盾する（しかしgitとしてはコンフリクトしない）ロジックが含まれていたようなケースです。

うちのチームでの直近の発生は、2022年9月、2024年11月にあったようでした。そこまで開発がアクティブではないプロダクトだからか頻繁とはいえないですが、防げるものなら防ぎたいです。

# アプローチ

* ベースブランチが古くなっていても、マージしたコードでテストする
  * CIツール（Jenkins, CircleCI）をどのように設定すれば、マージしたコードでテストできるか
* マージ前にブランチを最新に更新する
  * ベースブランチが古くなっている場合は更新するよう促すまたは強制する

上記のようなアプローチで、現在できることをまとめました。

# Jenkinsでの対応

GitHubでは、PRを作成すると `pull/{PR番号}/merge` というPRブランチをベースブランチにマージした結果の状態を持つブランチがremoteに作られます。そのブランチを、 [GitHub Pull Request Builder](https://plugins.jenkins.io/ghprb/) を使ってビルドする際の「ビルドするブランチ」に指定する形で実現します。

Jenkinsジョブの設定の要点は、以下のとおりです。

* `ソースコード管理` にて、以下の指定をする
  * 高度な設定＞Refspec に `+refs/pull/*:refs/remotes/origin/pr/*` を設定
  * ビルドするブランチ＞ブランチ指定子 に `${sha1}` という文字列を指定
* `GitHub Pull Request Builder` プラグインを有効にする
  * そうすると、PR作成時にCIが走るようになる

# CircleCIでの対応

`.circleci/config.yml` ファイルで [build-tools/merge-with-parent](https://circleci.com/developer/orbs/orb/circleci/build-tools#usage-merge-with-parent) を以下のように指定します。

```diff
    steps:
      - checkout
+     - build-tools/merge-with-parent:
+         parent: main
```

なお公式のExampleでは `parent: main` は書かれていませんが、これがないとmainブランチにpushされたときのビルドでも自身へのマージ処理が走ってエラーになっちゃうようでした。

# GitHub Actionsでの対応

まだActions使ってないので、未調査です。

# GitHubの設定

## ブランチを更新する提案

GitHubリポジトリの `settings` > `General` ページの `Pull Requests` セクションに `Always suggest updating pull request branches Loading` という設定項目があります（[ヘルプ](https://docs.github.com/ja/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-suggestions-to-update-pull-request-branches)）。これを有効にしていると、ベースブランチがPRブランチがよりも進んでいる場合に、以下のような「提案」をPR上に表示してくれます。

![screenshot_2024-12-11_18-19-30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107584/deb3c0ed-3fae-87bb-63b7-10325b26d47f.png)


PR作業者がこの「提案」をトリガーにrebaseなりmergeなりをしてブランチを更新すれば、CIが再度走るでしょう。

なお、この提案を無視してマージも可能ではあります。

## ブランチが最新状態であることを必須とする

GitHubリポジトリの `settings` ＞ `Rules` > `Ruleset` にて、 `Require status checks to pass before merging` を有効にすると、サブオプションとして `Require branches to be up to date before merging` が選べます（[ヘルプ](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets#require-status-checks-to-pass-before-merging)）。これを有効にしていると、CIチェックがOKでも、ベースブランチに対して最新でない場合はマージボタンが使えません。

![screenshot_2024-12-11_18-46-30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107584/b2d247e5-3153-8865-425e-873e3ac13875.png)

マージできないので前述の「提案」よりも安全ですが、mainブランチが頻繁に進むような活発なリポジトリで、CIチェックに時間がかかるような場合、何度更新してもなかなかマージできない事態に陥る懸念はあります。

また純粋に、明らかに自PRと無関係な修正がmainブランチに入ったケースにおいても更新を強いられるのは、正直だるいです。

# 考慮事項

上記のように、CIツール上の設定で、mainブランチとマージしたコードでテストすることできます。これで、PRを作った段階では、マージ後のエラーを事前に知ることはできます。

ただ、PRがオープンなうちにmainブランチの方が進んでしまった場合、その最新コードでテストし直さないとマージ後のエラーのリスクはあります。かといって、mainブランチが進むたびにPRブランチをビルドし直すようなことは現実的でないです。

よって、前述の「ブランチを更新する提案」を有効にしてmainブランチ側が進んでいるかを確認しつつ、必要に応じてブランチ更新して再テストをするのが、バランス良さそうだと個人的には思いました。
ベテランCTOの考えを徹底解剖！ 新しい組織に飛び込んだときのエンジニア組織の作り方を視聴してキャリアアップに踏み出せたエンジニアが印象に残ったポイントや学びをまとめてみた📝

この記事は [ex-crowdworks Advent Calendar 2024](https://qiita.com/advent-calendar/2024/ex-cw)の12日目の記事です。

# はじめに
今年、株式会社クラウドワークスを退職した@nisyuuです。お気に入りのアンテナショップは[いわて銀河プラザ](https://www.iwate-ginpla.net/)です。海宝漬が美味しいですよ。
エンジニアとしてクラウドワークステック（旧クラウドテック）というフリーランスと企業をマッチングするエージェントサービスを開発していました。

キャリアアップについて悩んでいた今年の2月に、「ベテランCTOの考えを徹底解剖！ 新しい組織に飛び込んだときのエンジニア組織の作り方」というイベントに参加しました。
その中で特に印象に残ったポイントや学びを記事にしてみたので、今後のキャリアにお悩みの方はどうぞご覧ください。
このイベントの後、私はキャリアアップに踏み出せているので少なからず誰かのキャリアにもプラスになるのではないかと考えています。

イベントはYouTubeにアーカイブが残っているので、お時間ある方は動画もご視聴いただけます。

<iframe width="560" height="315" src="https://www.youtube.com/embed/6C8BHDMcv5k?si=1bL9QX2UnzL11qmZ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

# ソフトスキルだけでなくハードスキルも磨く
エンジニアとして重要なのは、ソフトスキル（コミュニケーション能力や柔軟な思考力など）だけでなく、ハードスキル（技術的専門知識や開発スキル）も並行して磨くことです。
ハードスキルは具体的な成果を生み出すとともに、信頼を得るための基盤となります。

# 信頼構築の基本: 委任↔信頼↔依頼
エンジニア組織の基盤は信頼関係にあります  
- **まずは信頼を得る**ことが最優先です  
- 信頼があるからこそ、スムーズな委任と依頼が可能になります
- 信頼は課題解決を通して少しずつ積み重ねできます

# 課題解決を通した信頼の積み重ね方
1. **小さい課題から始める**  
   自己完結しやすい小規模な課題から取り組むことで、早期に成果が出しやすくなります
2. **いきなり解決せず、課題を共有する**  
   チーム全体で課題を共有し、共通認識を持つことで、効果的な解決策を模索できます
3. **複数の小さな信頼を積み重ねる**  
   一人からの大きな信頼を得ることを目指すより、多数からの小さな信頼を積み重ねた方が、組織全体で強固な土台を築けます

# 課題を見つける方法
- **1on1を活用**して直接ヒアリングを行う  
- 課題と断定する前に、現状や悩みを共有し、真の問題点を探る  
- ケーススタディを収集し、自らの組織状況に当てはめて考える

# 共感と受容
課題解決や信頼構築の過程では、**共感と受容**が非常に重要です  
- 他者の考えに必ずしも同意する必要はありませんが、受け入れる姿勢を持つことが大切です  
- 合理的な判断が難しい状況では、認知バイアスを理解・活用し、柔軟な対応を図ります  
- 論理面だけでなく感情面でも「腹落ち」する形を目指しましょう

# 間接メリットと直接メリット
- 間接的なメリットは訴求力が弱いため、**直接的なメリット**を意識し、行動や結果にフォーカスすることが信頼獲得の近道となります

# 信頼関係を観察する
信頼関係は相関的であり、自分の立ち位置を客観的に観察することが組織内での成長に有益です  
- 自分に不足している部分を認識する  
- ネガティブな評価からも事象を客観的に判断し、改善点を見出す

# ウィンザー効果の活用
**ウィンザー効果**とは、第三者からの評価が信頼構築に大きな影響力を持つことを指します  
- 自分の発信だけでなく、他者の評価や声をうまく活用することで、信頼を高めやすくなります

# ルールを決め、習慣化する
組織内で信頼を深め、安定した運営をするためには再現性ある行動が求められます  
- 明確なルールを定める  
- そのルールを習慣化し、組織に安定したリズムをもたらす  
- 情報収集を怠らず、常に再現性や改善点を意識することが重要です

# おわりに
イベントを通して、第一線で活躍してきたエンジニアから学ぶことは多くありました。
ちょうど、イベント参加時は今後のキャリアについて悩んでいた時期なので、キャリアアップに成功した自分の現状を踏まえるとかなりプラスに働いたイベントだったと思います。