Open7

Check! GitHub Actions スクラップブック

Kazumi OHIRA / dzKazumi OHIRA / dz

GitHub Actions の release トリガの type について

https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows#release

これまでの検証による結果と予測。予測の部分は後で確認して記事化したい。

トリガの type 契機 要検証
published リリースまたはプレリリースを公開したとき 済み
unpublished リリースまたはプレリリースの公開を取りやめたとき(予測) 要検証
created リリースまたはプレリリースを作成したとき。ドラフトも含まれると思われる(予測) ドラフトは含まれない 済み
edited リリースまたはプレリリースを変更したとき ドラフトの時の動作を検証したい
deleted リリースを削除したとき(予測) 要検証
prereleased プレリリースを公開したとき 済み
released リリースを公開したとき(予測) 要検証

例えば、「プレリリースを、作成して公開したとき」は、publishedprereleasedcreated のトリガが実行されることは確認済み。ドラフトを作成してない場合です。

Kazumi OHIRA / dzKazumi OHIRA / dz

https://github.com/marketplace/actions/variable-substitution

  • JSON, YAML, XML のファイルの、指定した値を変更できるアクション。追加はできない。
  • Microsoft Azure において利用する想定のアクションのようだが、JSON, YAML についてはほかの用途でも利用できそう
  • XML で利用する場合は制限あり(下記参照)

JSON, YAML の場合

例えば以下の書き方だと、

    - uses: microsoft/variable-substitution@v1 
      with:
        files: target.json, target.yml
      env:
        Var1: "value1"
        Var2.key1: "value2"

この構造で値が置き換わる

target.json
{
  "Var1": "value1",
  "Var2": {
    "key1": "value2"
  },
  "Var3": "Not replaced"
}
target.yml
Var1: value1
Var2:
  key1: value2
Var3: Not replaced

XML の場合

前述のように、Azure での利用を想定したアクションのため、特定のタグで特定の記述にしか反映されない。なお、xml の読み込みに失敗すると yaml として扱われてしまう。

    - uses: microsoft/variable-substitution@v1
      with:
        files: target.xml
      env:
        body: Hooray!
        nested.body: Fine!
target.xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="customizedSection" type="" />
  </configSections>
  <connectionStrings>
    <add name="body" connectionString="Hello world" />
    <add name="nested.body" connectionString="How are you?" />
  </connectionStrings>
  <appSettings>
    <add key="body" value="Hollo world" />
    <add key="nested.body" value="How are you?" />
  </appSettings>
  <applicationSettings>
    <myCustomSection>
      <setting name="body" serializeAs="String">
          <value>Hello world</value>
      </setting>
      <setting name="nested.body" serializeAs="String">
          <value>How are you?</value>
      </setting>
    </myCustomSection>
  </applicationSettings>
  <customizedSection>
    <parameters>
      <parameter body="Hello world" />
    </parameters>
  </customizedSection>
</configuration>
反映後
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="customizedSection" type=""/>
  </configSections>
  <connectionStrings>
    <add name="body" connectionString="Hooray!"/>
    <add name="nested.body" connectionString="Fine!"/>
  </connectionStrings>
  <appSettings>
    <add key="body" value="Hooray!"/>
    <add key="nested.body" value="Fine!"/>
  </appSettings>
  <applicationSettings>
    <myCustomSection>
      <setting name="body" serializeAs="String">
          <value>Hooray!</value>
      </setting>
      <setting name="nested.body" serializeAs="String">
          <value>Fine!</value>
      </setting>
    </myCustomSection>
  </applicationSettings>
  <customizedSection>
    <parameters>
      <parameter body="Hooray!"/>
    </parameters>
  </customizedSection>
</configuration>
Kazumi OHIRA / dzKazumi OHIRA / dz

xml で <configSections> を利用する場合は、この記法を守らないと xml が正しく読み込まれない。

https://docs.microsoft.com/ja-jp/dotnet/framework/configure-apps/file-schema/section-element

<configrations>
  <configSections>
    <!-- name と type 属性は必須 -->
    <section name="customizedSection" type=""/>
  </configSections>
  <customizedSection>
    <parameters>
      <parameter body="Hello world"/>
    </parameters>
  </customizedSection>
</configuration>
Kazumi OHIRA / dzKazumi OHIRA / dz

GitHub Actions で XML を編集するには LINQ to XML を PowerShell で使うのが便利そう!

LINQ to XML

C#のライブラリ。PowerShell は C# のライブラリを使えるので、わざわざ C#のコード書かなくてもよいのは助かる。

https://docs.microsoft.com/ja-jp/dotnet/standard/linq/linq-xml-overview

ちょっとコツがいるけど、PowerShell デフォルトで用意されている System.Xml.XmlDocument 使ってゴリゴリやるよりは使いやすい気がしました。

こちらは XmlDocument でゴリゴリ書いたサンプル。新規オブジェクトを作るのが見通しが悪い。(私の知識が足りないだけかもしれませんが…)

# Read xml file
$pomxml = [xml](Get-Content -Path pom.xml)
$ns = New-Object -TypeName "Xml.XmlNamespaceManager" -ArgumentList $pomxml.NameTable
$ns.AddNamespace("ns", "http://maven.apache.org/POM/4.0.0")

# Create new element
$configuration = $pomxml.CreateElement('configuration')
$gpgArguments = $pomxml.CreateElement('gpgArguments')
$arg = $pomxml.CreateElement('arg')
$arg.InnerText = "--pinentry-mode"
$gpgArguments.AppendChild($arg.clone())
$arg.InnerText = "loopback"
$gpgArguments.AppendChild($arg.clone())
$configuration.AppendChild($gpgArguments)

# Add the element to the specified node
$plugin = $pomxml.SelectNodes("//ns:plugin[ns:artifactId[text()='maven-gpg-plugin']]", $ns)
$plugin.executions.execution.AppendChild($configuration)

こちらが LINQ to XML を利用したサンプル。新規オブジェクト作るのが見通しがよい。

# Read xml file
[Reflection.Assembly]::LoadWithPartialName("System.Xml.Linq")
$path = "pom.xml"
$doc = [System.Xml.Linq.XElement]::Load($path)
$ns = $doc.GetDefaultnamespace()

# Create new element
$configurationElement = [System.Xml.Linq.XElement]::New(
  $ns + "configuration",
  [System.Xml.Linq.XElement]::New(
    $ns + "gpgArguments",
    [System.Xml.Linq.XElement]::New($ns + "arg", "--pinentry-mode"),
    [System.Xml.Linq.XElement]::New($ns + "arg", "loopback")
  )
)

# Add the element to the specified node
$plugin = $doc.Descendants($ns + "plugin").Where({$_.Element($ns + "artifactId").Value -eq "maven-gpg-plugin"})[0]
$plugin.Descendants($ns + "execution").Add($configurationElement)

GitHub Actions の run ステップで任意のシェルで実行する

steps:
  run: echo ${env:PATH}
  shell: pwsh

https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#using-a-specific-shell

どの場合も namespace がある場合はやっかい

System.Xml を使う場合でも、System.Xml.Linq を使う場合でも、ネームスペースの扱いは厄介。どのノードにもネームスペースを指定しないとならないよう。