mirror of
				https://github.com/docker/login-action.git
				synced 2025-10-31 18:20:10 +08:00 
			
		
		
		
	Feature: Enable Multi Registry login Authentication
Signed-off-by: unknown <arunkumarthiyagarajan95@gmail.com>
This commit is contained in:
		
							parent
							
								
									ef38ec311a
								
							
						
					
					
						commit
						8d9860ef0e
					
				
							
								
								
									
										31
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								README.md
									
									
									
									
									
								
							| @ -24,6 +24,7 @@ ___ | |||||||
|   * [OCI Oracle Cloud Infrastructure Registry (OCIR)](#oci-oracle-cloud-infrastructure-registry-ocir) |   * [OCI Oracle Cloud Infrastructure Registry (OCIR)](#oci-oracle-cloud-infrastructure-registry-ocir) | ||||||
|   * [Quay.io](#quayio) |   * [Quay.io](#quayio) | ||||||
|   * [DigitalOcean](#digitalocean-container-registry) |   * [DigitalOcean](#digitalocean-container-registry) | ||||||
|  |   * [Multiple Registries](#multiple-registries) | ||||||
| * [Customizing](#customizing) | * [Customizing](#customizing) | ||||||
|   * [inputs](#inputs) |   * [inputs](#inputs) | ||||||
| * [Contributing](#contributing) | * [Contributing](#contributing) | ||||||
| @ -494,6 +495,34 @@ jobs: | |||||||
|           password: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} |           password: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | ### Multiple Registries | ||||||
|  | You can login to multiple registries by providing a multiline string for the registry input. Each registry will be processed sequentically using the same username and password. | ||||||
|  | 
 | ||||||
|  | ```yaml | ||||||
|  | name: ci | ||||||
|  | 
 | ||||||
|  | on: | ||||||
|  |   push: | ||||||
|  |     branches: main | ||||||
|  | 
 | ||||||
|  | jobs: | ||||||
|  |   login: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |       - | ||||||
|  |         name: Login to Multiple Regsitries | ||||||
|  |         uses: docker/login-action@v7 | ||||||
|  |         with: | ||||||
|  |           registry: | | ||||||
|  |             ghcr.io | ||||||
|  |             docker.io | ||||||
|  |             registry.gitlab.com | ||||||
|  |           # for single registry,  | ||||||
|  |           # registry: "ghcr.io" | ||||||
|  |           username: ${{ vars.REGISTRY_USERNAME }} | ||||||
|  |           password: ${{ secrets.REGISTRY_PASSWORD }} | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
| ## Customizing | ## Customizing | ||||||
| 
 | 
 | ||||||
| ### inputs | ### inputs | ||||||
| @ -502,7 +531,7 @@ The following inputs can be used as `step.with` keys: | |||||||
| 
 | 
 | ||||||
| | Name       | Type   | Default | Description                                                                   | | | Name       | Type   | Default | Description                                                                   | | ||||||
| |------------|--------|---------|-------------------------------------------------------------------------------| | |------------|--------|---------|-------------------------------------------------------------------------------| | ||||||
| | `registry` | String |         | Server address of Docker registry. If not set then will default to Docker Hub | | | `registry` | String |         | Server address of Docker registry. If not set then will default to Docker Hub. Supports multiline string for multiplr registries. | | ||||||
| | `username` | String |         | Username for authenticating to the Docker registry                            | | | `username` | String |         | Username for authenticating to the Docker registry                            | | ||||||
| | `password` | String |         | Password or personal access token for authenticating the Docker registry      | | | `password` | String |         | Password or personal access token for authenticating the Docker registry      | | ||||||
| | `ecr`      | String | `auto`  | Specifies whether the given registry is ECR (`auto`, `true` or `false`)       | | | `ecr`      | String | `auto`  | Specifies whether the given registry is ECR (`auto`, `true` or `false`)       | | ||||||
|  | |||||||
| @ -20,17 +20,34 @@ test('loginStandard calls exec', async () => { | |||||||
| 
 | 
 | ||||||
|   const username = 'dbowie'; |   const username = 'dbowie'; | ||||||
|   const password = 'groundcontrol'; |   const password = 'groundcontrol'; | ||||||
|   const registry = 'https://ghcr.io'; |   // Define const registry as multiline input
 | ||||||
|  |   const registry = `https://ghcr.io
 | ||||||
|  | https://docker.io`;
 | ||||||
| 
 | 
 | ||||||
|   await loginStandard(registry, username, password); |   const registryArray = registry.split('\n').map(r => r.trim()); | ||||||
| 
 | 
 | ||||||
|   expect(execSpy).toHaveBeenCalledTimes(1); |   for (const reg of registryArray) { | ||||||
|   const callfunc = execSpy.mock.calls[0]; |     await loginStandard(reg, username, password); | ||||||
|   if (callfunc && callfunc[1]) { |  | ||||||
|     // we don't want to check env opt
 |  | ||||||
|     callfunc[1].env = undefined; |  | ||||||
|   } |   } | ||||||
|   expect(execSpy).toHaveBeenCalledWith(['login', '--password-stdin', '--username', username, registry], { | 
 | ||||||
|  |   expect(execSpy).toHaveBeenCalledTimes(2); | ||||||
|  |   const firstcall = execSpy.mock.calls[0]; | ||||||
|  |   if (firstcall && firstcall[1]) { | ||||||
|  |     // we don't want to check env opt
 | ||||||
|  |     firstcall[1].env = undefined; | ||||||
|  |   } | ||||||
|  |   expect(execSpy).toHaveBeenCalledWith(['login', '--password-stdin', '--username', username, registryArray[0]], { | ||||||
|  |     input: Buffer.from(password), | ||||||
|  |     silent: true, | ||||||
|  |     ignoreReturnCode: true | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   const secondcall = execSpy.mock.calls[1]; | ||||||
|  |   if (secondcall && secondcall[1]) { | ||||||
|  |     // we don't want to check env opt
 | ||||||
|  |     secondcall[1].env = undefined; | ||||||
|  |   } | ||||||
|  |   expect(execSpy).toHaveBeenCalledWith(['login', '--password-stdin', '--username', username, registryArray[1]], { | ||||||
|     input: Buffer.from(password), |     input: Buffer.from(password), | ||||||
|     silent: true, |     silent: true, | ||||||
|     ignoreReturnCode: true |     ignoreReturnCode: true | ||||||
| @ -48,17 +65,32 @@ test('logout calls exec', async () => { | |||||||
|     }; |     }; | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|   const registry = 'https://ghcr.io'; |   const registry = `https://ghcr.io
 | ||||||
|  | https://docker.io`;
 | ||||||
| 
 | 
 | ||||||
|   await logout(registry); |   const registryArray = registry.split('\n').map(r => r.trim()); | ||||||
| 
 | 
 | ||||||
|   expect(execSpy).toHaveBeenCalledTimes(1); |   for (const reg of registryArray) { | ||||||
|   const callfunc = execSpy.mock.calls[0]; |     await logout(reg); | ||||||
|   if (callfunc && callfunc[1]) { |  | ||||||
|     // we don't want to check env opt
 |  | ||||||
|     callfunc[1].env = undefined; |  | ||||||
|   } |   } | ||||||
|   expect(execSpy).toHaveBeenCalledWith(['logout', registry], { | 
 | ||||||
|  |   expect(execSpy).toHaveBeenCalledTimes(2); | ||||||
|  |   const firstcall = execSpy.mock.calls[0]; | ||||||
|  |   if (firstcall && firstcall[1]) { | ||||||
|  |     // we don't want to check env opt
 | ||||||
|  |     firstcall[1].env = undefined; | ||||||
|  |   } | ||||||
|  |   expect(execSpy).toHaveBeenCalledWith(['logout', registryArray[0]], { | ||||||
|  |     ignoreReturnCode: true | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   const secondcall = execSpy.mock.calls[1]; | ||||||
|  |   if (secondcall && secondcall[1]) { | ||||||
|  |     // we don't want to check env opt
 | ||||||
|  |     secondcall[1].env = undefined; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   expect(execSpy).toHaveBeenCalledWith(['logout', registryArray[1]], { | ||||||
|     ignoreReturnCode: true |     ignoreReturnCode: true | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import * as core from '@actions/core'; | import * as core from '@actions/core'; | ||||||
| 
 | 
 | ||||||
| export interface Inputs { | export interface Inputs { | ||||||
|   registry: string; |   registry: string[]; | ||||||
|   username: string; |   username: string; | ||||||
|   password: string; |   password: string; | ||||||
|   ecr: string; |   ecr: string; | ||||||
| @ -10,7 +10,7 @@ export interface Inputs { | |||||||
| 
 | 
 | ||||||
| export function getInputs(): Inputs { | export function getInputs(): Inputs { | ||||||
|   return { |   return { | ||||||
|     registry: core.getInput('registry'), |     registry: core.getMultilineInput('registry'), | ||||||
|     username: core.getInput('username'), |     username: core.getInput('username'), | ||||||
|     password: core.getInput('password'), |     password: core.getInput('password'), | ||||||
|     ecr: core.getInput('ecr'), |     ecr: core.getInput('ecr'), | ||||||
|  | |||||||
							
								
								
									
										11
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								src/main.ts
									
									
									
									
									
								
							| @ -4,18 +4,23 @@ import * as context from './context'; | |||||||
| import * as docker from './docker'; | import * as docker from './docker'; | ||||||
| import * as stateHelper from './state-helper'; | import * as stateHelper from './state-helper'; | ||||||
| 
 | 
 | ||||||
| export async function main(): Promise<void> { |  | ||||||
| const input: context.Inputs = context.getInputs(); | const input: context.Inputs = context.getInputs(); | ||||||
|  | 
 | ||||||
|  | export async function main(): Promise<void> { | ||||||
|   stateHelper.setRegistry(input.registry); |   stateHelper.setRegistry(input.registry); | ||||||
|   stateHelper.setLogout(input.logout); |   stateHelper.setLogout(input.logout); | ||||||
|   await docker.login(input.registry, input.username, input.password, input.ecr); |   for (const reg of input.registry) { | ||||||
|  |     await docker.login(reg, input.username, input.password, input.ecr); | ||||||
|  |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| async function post(): Promise<void> { | async function post(): Promise<void> { | ||||||
|   if (!stateHelper.logout) { |   if (!stateHelper.logout) { | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   await docker.logout(stateHelper.registry); |   for (const reg of input.registry) { | ||||||
|  |     await docker.logout(reg); | ||||||
|  |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| actionsToolkit.run(main, post); | actionsToolkit.run(main, post); | ||||||
|  | |||||||
| @ -3,8 +3,9 @@ import * as core from '@actions/core'; | |||||||
| export const registry = process.env['STATE_registry'] || ''; | export const registry = process.env['STATE_registry'] || ''; | ||||||
| export const logout = /true/i.test(process.env['STATE_logout'] || ''); | export const logout = /true/i.test(process.env['STATE_logout'] || ''); | ||||||
| 
 | 
 | ||||||
| export function setRegistry(registry: string) { | export function setRegistry(registry: string[]) { | ||||||
|   core.saveState('registry', registry); |   core.info(`Setting registry: ${registry.join(',')}`); | ||||||
|  |   core.saveState('registry', registry.join(',')); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function setLogout(logout: boolean) { | export function setLogout(logout: boolean) { | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 unknown
						unknown