summaryrefslogtreecommitdiff
path: root/pipelines/debian.ick
blob: 1f8e5c58e74f172bc1e0d4b69fa72cbe9a740b55 (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
# Lars Wirzenius.
# 
# Feel free to use this as you wish. It is simple enough that it is
# probably not even copyrightable.

pipelines:

  # Install APT signing keys from the apt_signing_pub_keys parameter.
  # The parameter should contain a dict, where each item is the name
  # of a signing key, and is used as the filename in
  # /etc/apt/trusted.gpg.d. The dict value is the actual public key,
  # in gpg --export --armore format.

  - pipeline: ick/add_apt_signing_keys
    parameters:
      - apt_signing_pub_keys
    actions:
      - python: |
          for name, key in params['apt_signing_pub_keys'].items():
            filename = '/etc/apt/trusted.gpg.d/{}.asc'.format(name)
            print('Writing key to', filename)
            with open(filename, 'w') as f:
              f.write(key)
        where: container

  # Install APT sources listed in the parameter apt_sources by
  # creating /etc/apt/sources.list.d/ick_apt_sources.list from the
  # list. Each list item must be a dict with fields url, codename,
  # section. For example:
  #
  #     apt_sources:
  #     - url: deb.example.com
  #       dist: unstable
  #       section: main
  #       key: CAFEBEEF
  #     - url: deb.example.com
  #       dist: unstable
  #       section: contrib
  #       key: CAFEBEEF

  - pipeline: ick/add_apt_sources
    parameters:
      - apt_sources
    actions:
      - python: |
          apts = params['apt_sources']
          filename = '/etc/apt/sources.list.d/ick_apt_sources.list'
          print('Creating', filename)
          with open(filename, 'w') as f:
            for apt in apts:
              f.write('deb {url} {dist} {section}\n'.format(**apt))
        where: container

      - shell: |
          apt-get update
        where: container

  # Install build-dependencies for a Debian build, by checking
  # debian/control for what's missing. The sources parameter is used
  # to find all the source trees: for each location, if debian/oontrol
  # exists as the location, look for missing build-dependencies.

  - pipeline: ick/install_debian_build_dependencies
    parameters:
      - sources
    actions:
      - python: |
          import os, subprocess

          def RUN(*args, **kwargs):
            print('Executing:', args, kwargs)
            if 'check' not in kwargs:
              kwargs['check'] = True
            return subprocess.run(args, **kwargs)

          def OUT(*args, **kwargs):
            x = RUN(*args, stdout=subprocess.PIPE, **kwargs)
            return x.stdout.decode('UTF-8')

          def ERR(*args, **kwargs):
            x = RUN(*args, stderr=subprocess.PIPE, check=False, **kwargs)
            return x.stderr.decode('UTF-8')

          def is_package_name(s):
            ok = "abcdefghijklmnopqrstyuvwxyz"
            ok += ok.upper()
            ok += "0123456789.-"
            return all(c in ok for c in s)

          sources = params['sources']
          for source in sources:
            dirname = source['location']
            control = os.path.join(dirname, 'debian', 'control')
            if os.path.exists(control):
              RUN('apt', 'show', 'python-coverage-test-runner', check=False)
              RUN('apt', 'show', 'python3-coverage-test-runner', check=False)
              err = ERR('dpkg-checkbuilddeps', cwd=dirname)
              print('err', err)
              pat = 'Unmet build dependencies: '
              if pat in err:
                parts = err.split(pat)
                print('parts:', repr(parts))
                missing = [x for x in parts[1].split() if is_package_name(x)]
                print('missing', missing)
                for name in missing:
                  RUN('apt-get', 'install', '-y', name)
        where: container


  # Build Debian packages. This is a CI build, which means a new
  # debian/changelog entry is created, with a version number that
  # contains the build number. This way every build results in a new
  # package version.
  #
  # The build will be done in each location in the sources parameter,
  # where debian/control exists.

  - pipeline: ick/build_deb_ci
    parameters:
      - sources
      - distribution
    actions:
      - python: |
          import os, subprocess

          def RUN(*args, **kwargs):
              print('Executing:', args, kwargs)
              return subprocess.run(args, check=True, **kwargs)

          def OUT(*args, **kwargs):
              x = RUN(*args, stdout=subprocess.PIPE, **kwargs)
              return x.stdout.decode('UTF-8')

          sources = params['sources']
          distribution = params['distribution']
          for source in sources:
              dirname = source['location']
              control = os.path.join(dirname, 'debian', 'control')
              print('looking for', control)
              if os.path.exists(control):
                  print('building in', dirname)
                  src = OUT('dpkg-parsechangelog', '-S', 'Source', cwd=dirname)
                  src = src.strip()
                  print('src', repr(src))
                  assert src

                  ver = OUT('dpkg-parsechangelog', '-S', 'Version', cwd=dirname)
                  print('ver', repr(ver))
                  assert ver

                  if '-' in ver:
                      parts = ver.split('-')
                      ver = '-'.join(parts[:-1])
                      ver += '.0ci{}'.format(os.environ['BUILD_NUMBER'])
                      print('ver', repr(ver))

                      tarball = '../{}_{}.orig.tar.xz'.format(src, ver)
                      print('tarball', repr(tarball))

                      RUN('dch', '-v', '{}-1'.format(ver), '--distribution', distribution,
                          '--force-distribution', 'CI build', cwd=dirname)
                      RUN('dch', '-r', '', cwd=dirname)
                      RUN('sh', '-c', 'git archive HEAD | xz > {}'.format(tarball), cwd=dirname)
                      RUN('dpkg-buildpackage', '-us', '-uc', cwd=dirname)
        where: container

  # Upload all *.changes files at the root of the workspace.

  - pipeline: ick/upload_debs
    actions:
      - action: dput
        where: host