summaryrefslogtreecommitdiff
path: root/.github/workflows/bundled_gems.yml
blob: f12bc849b16551738eb162265af9135e16f06cdd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
name: bundled_gems

env:
  UPDATE_NEWS_ENABLED: false

on:
  push:
    branches: ['master']
    paths:
      - '.github/workflows/bundled_gems.yml'
      - 'gems/bundled_gems'
  pull_request:
    branches: ['master']
    paths:
      - '.github/workflows/bundled_gems.yml'
      - 'gems/bundled_gems'
  merge_group:
  schedule:
    - cron: '45 6 * * *'
  workflow_dispatch:

permissions: # added using https://github.com/step-security/secure-workflows
  contents: read

jobs:
  update:
    permissions:
      contents: write # for Git to git push

    if: ${{ github.event_name != 'schedule' || github.repository == 'ruby/ruby' }}

    name: update ${{ github.workflow }}

    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
        with:
          token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }}

      - uses: ./.github/actions/setup/directories
        with:
          # Skip overwriting MATZBOT_AUTO_UPDATE_TOKEN
          checkout: '' # false (ref: https://github.com/actions/runner/issues/2238)

      - name: Set ENV
        run: |
          echo "TODAY=$(date +%F)" >> $GITHUB_ENV

      - name: Download previous gems list
        run: |
          mkdir -p .downloaded-cache
          for data in bundled_gems.json default_gems.json; do
            ln -s .downloaded-cache/$data .
            curl -O -R -z ./$data https://stdgems.org/$data
          done

      - name: Update bundled gems list
        id: bundled_gems
        run: |
          ruby -i~ tool/update-bundled_gems.rb gems/bundled_gems >> $GITHUB_OUTPUT
        if: ${{ env.UPDATE_NEWS_ENABLED == 'true' }}

      - name: Update spec/bundler/support/builders.rb
        run: |
          #!ruby
          rake_version = File.read("gems/bundled_gems")[/^rake\s+(\S+)/, 1]
          print ARGF.read.sub(/^ *def rake_version\s*\K".*?"/) {rake_version.dump}
        shell: ruby -i~ {0} spec/bundler/support/builders.rb
        if: ${{ env.UPDATE_NEWS_ENABLED == 'true' }}

      - name: Maintain updated gems list in NEWS
        run: |
          ruby tool/update-NEWS-gemlist.rb bundled
        if: ${{ env.UPDATE_NEWS_ENABLED == 'true' }}

      - name: Check diffs
        id: diff
        run: |
          news= gems=
          git diff --color --no-ext-diff --ignore-submodules --exit-code -- NEWS.md ||
          news=true
          git diff --color --no-ext-diff --ignore-submodules --exit-code -- gems/bundled_gems ||
          gems=true
          git add -- NEWS.md gems/bundled_gems
          git add -- spec/bundler/support/builders.rb
          echo news=$news >> $GITHUB_OUTPUT
          echo gems=$gems >> $GITHUB_OUTPUT
          echo update=${news:-$gems} >> $GITHUB_OUTPUT

      - name: Commit
        id: commit
        run: |
          git pull --ff-only origin ${GITHUB_REF#refs/heads/}
          message="Update bundled gems list"
          if [ -z "${gems}" ]; then
            git commit --message="[DOC] ${message} at ${GITHUB_SHA:0:30}"
          else
            git commit --message="${message} as of ${TODAY}"
          fi
        env:
          TODAY: ${{ steps.bundled_gems.outputs.latest_date || env.TODAY }}
          EMAIL: svn-admin@ruby-lang.org
          GIT_AUTHOR_NAME: git
          GIT_COMMITTER_NAME: git
          gems: ${{ steps.diff.outputs.gems }}
        if: ${{ steps.diff.outputs.update }}

      - name: Development revision of bundled gems
        run: |
          #!ruby
          file = "gems/bundled_gems"

          SECONDS_IN_DAY = 86400
          today = Time.new("#{ENV['TODAY']}Z")
          if !(december = today.month == 12)
            days = 30
          elsif (days = 26 - today.day).positive?
            days += 4
          else
            puts "::info:: just after released"
            exit
          end

          since = "#{today.year-1}-12-26"
          ref = ENV['GITHUB_REF']
          puts "::group::\e[94mfetching \e[1m#{file}\e[22m since \e[1m#{since}\e[22m from \e[1m#{ref}\e[m"
          system(*%W[git fetch --shallow-since=#{since} --no-tags origin #{ref}], exception: true)
          puts "::endgroup::"

          puts "\e[94mchecking development version bundled gems older than \e[1m#{days}\e[22m days\e[m"
          limit = today.to_i - days * SECONDS_IN_DAY
          old = 0
          IO.popen(%W"git blame --line-porcelain -- #{file}") do |blame|
            while head = blame.gets("\n\t") and s = blame.gets
              next unless (gem = s.split(/\s+|#.*/)).size > 3
              time = head[/^committer-time \K\d+/].to_i
              next if (d = limit - time) <= 0
              d /= SECONDS_IN_DAY
              line = head[/\A\h+ \d+ \K\d+/].to_i
              level = if d < days; 'warning'; else old += 1; 'error'; end
              d += days
              puts "::#{level} file=#{file},line=#{line},title=Older than #{d} days::#{gem[0]} #{gem[3]}"
            end
          end
          abort "::error title=Too long-standing gems::The release comes soon." if december and old.nonzero?
        shell: ruby {0}
        env:
          file: ${{ steps.logs.outputs.file }}
          days: ${{ steps.logs.outputs.days }}

      - name: Install libraries
        uses: ./.github/actions/setup/ubuntu
        if: ${{ steps.diff.outputs.gems }}

      - name: Build
        run: |
          ./autogen.sh
          ./configure -C --disable-install-doc
          make
        if: ${{ steps.diff.outputs.gems }}

      - name: Prepare bundled gems
        run: |
          make -s prepare-gems
        if: ${{ steps.diff.outputs.gems }}

      - name: Test bundled gems
        run: |
          make -s test-bundled-gems
        timeout-minutes: 30
        env:
          RUBY_TESTOPTS: '-q --tty=no'
          TEST_BUNDLED_GEMS_ALLOW_FAILURES: ''
        if: ${{ steps.diff.outputs.gems }}

      - name: Push
        run: |
          git push origin ${GITHUB_REF#refs/heads/}
        if: >-
          ${{
          github.repository == 'ruby/ruby' &&
          !startsWith(github.event_name, 'pull') &&
          steps.commit.outcome == 'success'
          }}

      - uses: ./.github/actions/slack
        with:
          SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
        if: ${{ failure() }}