forked from sparklemotion/nokogiri
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdocker.rake
148 lines (130 loc) · 4.56 KB
/
docker.rake
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
# frozen_string_literal: true
#
# docker docker docker
#
module DockerHelper
IMAGE_DIR = "oci-images/nokogiri-test"
IMAGE_NAME = "ghcr.io/sparklemotion/nokogiri-test"
RUBIES = {
mri: ["3.0", "3.1", "3.2", "3.3"],
}
class << self
def docker_tag_for(engine, version = nil)
[engine, version].compact.join("-")
end
def docker_file_for(engine, version = nil)
File.join(IMAGE_DIR, "#{docker_tag_for(engine, version)}.dockerfile")
end
def docker_image_for(engine, version = nil)
"#{IMAGE_NAME}:#{docker_tag_for(engine, version)}"
end
def docker_files_each
Dir[File.join(IMAGE_DIR, "*.erb")].each do |template_path|
tag_or_engine = File.basename(template_path).gsub(/(.*)\.erb/, '\1').to_sym
if RUBIES.key?(tag_or_engine)
# engine
RUBIES[tag_or_engine].each do |version|
dockerfile_path = docker_file_for(tag_or_engine, version)
yield File.read(template_path), dockerfile_path, version, docker_image_for(tag_or_engine, version)
end
else
# tag
dockerfile_path = docker_file_for(tag_or_engine)
yield File.read(template_path), dockerfile_path, nil, docker_image_for(tag_or_engine)
end
end
end
def generate_pipeline
filename = File.join(".github", "workflows", "generate-ci-images.yml")
platforms = Dir.glob(File.join(IMAGE_DIR, "*.dockerfile")).sort.map do |dockerfile|
Regexp.new("(.*)\\.dockerfile").match(File.basename(dockerfile))[1]
end
contents = <<~YAML
# DO NOT EDIT
# this file is automatically generated by the "docker:pipeline" rake task
name: Generate CI Images
on:
workflow_dispatch: {}
schedule:
- cron: "0 5 * * 3" # At 05:00 on Wednesday # https://crontab.guru/#0_5_*_*_3
# reference: https://github.com/marketplace/actions/build-and-push-docker-images
jobs:
build_images:
strategy:
fail-fast: false
matrix:
tag: #{platforms.inspect}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: ruby/setup-ruby@v1
with:
ruby-version: "3.1"
bundler-cache: true
bundler: latest
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{github.actor}}
password: ${{secrets.GITHUB_TOKEN}}
- name: ${{matrix.tag}}
uses: docker/build-push-action@v6
with:
context: "."
push: true
tags: #{IMAGE_NAME}:${{matrix.tag}}
file: #{IMAGE_DIR}/${{matrix.tag}}.dockerfile
YAML
puts "writing #{filename} ..."
File.open(filename, "w") { |io| io.write(contents) }
end
def include_file(filename)
"# include_file #{filename}\n" + File.read(filename)
end
def generate_dockerfiles
require "erb"
DockerHelper.docker_files_each do |template, dockerfile_path, version, _|
puts "writing #{dockerfile_path} ..."
File.open(dockerfile_path, "w") do |dockerfile|
Dir.chdir(File.dirname(dockerfile_path)) do
dockerfile.write(ERB.new(template, trim_mode: "%-").result(binding))
end
end
end
end
end
end
namespace "docker" do
desc "Generate an Actions pipeline to take care of everything"
task "pipeline" => "generate" do
DockerHelper.generate_pipeline
end
desc "Generate Dockerfiles"
task "generate" do
DockerHelper.generate_dockerfiles
end
desc "Build docker images for testing"
task "build" do
DockerHelper.docker_files_each do |_, dockerfile_path, _, docker_image|
sh "docker build -t #{docker_image} -f #{dockerfile_path} ."
end
end
desc "Push a docker image for testing"
task "push" do
DockerHelper.docker_files_each do |_, _, _, docker_image|
sh "docker push #{docker_image}"
end
end
desc "Pull upstream docker images"
task "pull" do
DockerHelper.docker_files_each do |_, dockerfile_path, _, _|
upstream = File.read(dockerfile_path).lines.grep(/FROM/).first.split("FROM ").last
sh "docker pull #{upstream}"
end
end
end
desc "Build and push a docker image for testing"
task "docker" => ["docker:generate", "docker:pull", "docker:build", "docker:push"]